双向链表的创建以及增删改查

2023-11-05

实现起来其实不难,于是我把代码做了优化,模仿了stm32的库函数哈哈哈,便于理解和修改。不足之处请指出

#include "stdio.h"
#include "stdlib.h"

//宏定义
#define ElementType int
#define uint unsigned int

ElementType pa[6] = {1, 2, 2, 3, 5, 7};
ElementType pb[5] = {2, 3, 4, 6, 8};
ElementType *pc;
uint MaxLength1 = 6;
uint MaxLength2 = 5;
uint structLength = 0;

//结构体定义
typedef struct Node
{
    ElementType data;
    struct Node *next;
    struct Node *prior;
} LNode, *LinkList;

//标记作用的结构体定义
LinkList presentNode; //当前指向的结构体
LinkList headNode;    //头结点
LinkList finalNode;   //指向最后一个结构体

//运行是否成功标志位定义
uint FLAG;

//函数声明
//一级函数
void structInit(LNode *pNode);                               //结构体初始化
void printfStructData(LinkList pNode, uint nowStructLength); //打印链表数据
//增:
void structInsert(LNode *pNode, ElementType insertLocation, uint insertData); //在指定位置插入
void structInsertArray(LinkList pNode, ElementType *pData, uint dataLength);  //在末尾插入数组
//删
void deleteStructElement(LinkList pNode, uint deleteLocation);
//改
void changeStructElement(LinkList pNode, uint changeLocation, ElementType structData);
//查
void findStructElement(LinkList pNode, uint findLocation);
//二级函数(不会直接调用,一般是被一级函数用)
void checkNodeInsertLocation(uint flag); //检查结构体插入位置是否合理
void checkNodeCreat(LNode *Node);        //检查结构体是否创建成功
void checkError(uint flag);              //问题处理
void checkNodeIsEmpty(LNode *Node);      //检查链表是否为空链表

int main()
{
    LNode *Node1 = (LNode *)(malloc(sizeof(LNode)));
    checkNodeCreat(Node1);
    structInit(Node1);
    structInsertArray(headNode, pa, MaxLength1);
    printfStructData(headNode, structLength);
    deleteStructElement(headNode, 2);
    printfStructData(headNode, structLength);
    findStructElement(headNode, 3);
    printfStructData(headNode, structLength);
    changeStructElement(headNode, 3, 99);
    printfStructData(headNode, structLength);
    while (1);
    return 0;
}

/*
功能:初始化新建的链表
parameter:新建的链表的头结点
*/
void structInit(LNode *pNode)
{
    pNode->data = 0;
    pNode->prior = pNode;
    pNode->next = pNode;
    headNode = pNode;
    finalNode = pNode;
    presentNode = pNode;
}

/*
输出链表的每一个数据
parameter:
pNode:头结点
nowStructLength:当前链表长度
*/
void printfStructData(LinkList pNode, uint nowStructLength)
{
    uint flag = 0;
    while (nowStructLength != 0)
    {
        nowStructLength--;
        pNode = pNode->next;
        printf("%d", pNode->data);
        if (nowStructLength != 0)
        {
            printf("->");
        }
    }
    printf("\n");
}

/*
错误检索
功能:函数返回值检测,检测函数是否运行成功,如果失败,则报出对应的错误
parameter: 其他函数的返回值
*/
void checkError(uint flag)
{
    if (flag == 401)
        printf("\nERROR:401. Insert location is wrong. Can not be 0 or greater than structLength.\n");
    else if (flag == 501)
        printf("\nERROR:501. Creat struct is defated\n.");
    else if (flag == 502)
        printf("\nError:502. List is empty.\n");
}

/*
检查结构体是否创建成功
*/
void checkNodeCreat(LNode *Node)
{
    if (Node == NULL)
    {
        checkError(501);
    }
}

/*
检查链表是否为空
*/
void checkNodeIsEmpty(LNode *Node)
{
    if (Node->next == Node && Node->prior == Node)
    {
        checkError(502);
    }
}
/*
检查插入位置是否越界
parameter:
insertLocation:插入的位置
*/
void checkNodeInsertLocation(uint insertLocation)
{
    if (insertLocation < 1 || insertLocation > structLength + 1) //如果是空结构体,插入第一个,插入位置等于1,structLength+1=1,刚好不大于
        checkError(401);
}

/*
功能:给双向链表的指定位置插入数据
parameter:
pNpde:头结点
insertLocation:插入位置
insertData:插入数据值
eg:
插入位置:2,插入数据:6
插入前:头结点 1 2 3 4
插入后:头结点 1 6 2 3 4
*/
void structInsert(LinkList pNode, ElementType insertLocation, uint insertData)
{
    int i = 0;
    LNode *newNode = (LNode *)(malloc(sizeof(LNode)));
    checkNodeCreat(newNode);
    checkNodeInsertLocation(insertLocation);
    for (i = 0; i < insertLocation; i++)
    {
        pNode = pNode->next;
    }
    newNode->data = insertData;
    pNode->prior->next = newNode;
    newNode->prior = pNode->prior;
    newNode->next = pNode;
    pNode->prior = newNode;

    structLength++;
}

/*
功能:在结构体末尾连续插入一串数组。主要是用来结构体初始化,给刚创建的空链表赋一些值
parameter:
pNpde:要插入的链表的头结点
pData:传入的数组
dataLength:传入的数组的长度
*/
void structInsertArray(LinkList pNode, ElementType *pData, uint dataLength)
{
    uint flag;

    for (flag = 0; flag < dataLength; flag++)
    {
        structInsert(pNode, structLength + 1, *pData++);
    }
}

    /*
功能:给双向链表的指定位置删除数据
parameter:
pNpde:头结点
insertLocation:删除位置
eg:
删除位置:2
插入前:头结点 1 2 3 4
插入后:头结点 1 3 4
*/
    void
    deleteStructElement(LinkList pNode, uint deleteLocation)
{
    int i = 0;
    checkNodeCreat(pNode);
    checkNodeInsertLocation(deleteLocation);
    for (i = 0; i < deleteLocation; i++)
    {
        pNode = pNode->next;
    }
    printf("要删除的结点值为:%d\n", pNode->data);
    pNode->prior->next = pNode->next;
    pNode->next->prior = pNode->prior;
    free(pNode);

    structLength--;
}

/*
查找某一个结点的值
*/
void findStructElement(LinkList pNode, uint findLocation)
{
    int i = 0;
    checkNodeCreat(pNode);
    checkNodeInsertLocation(findLocation);
    for (i = 0; i < findLocation; i++)
    {
        pNode = pNode->next;
    }
    printf("要查找的元素值为%d\n", pNode->data);
}

//修改某一个结点的值
void changeStructElement(LinkList pNode, uint changeLocation, ElementType structData)
{
    int i = 0;
    checkNodeCreat(pNode);
    checkNodeInsertLocation(changeLocation);
    for (i = 0; i < changeLocation; i++)
    {
        pNode = pNode->next;
    }
    pNode->data = structData;
    printf("删除的元素为%d\n", pNode->data);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

双向链表的创建以及增删改查 的相关文章

  • 简洁而实用的NAS导航页——Homarr

    前言 为了更好管理家庭内网中部署的各个服务 尤其访问NAS docker中的容器 之前看过一些类似的导航面板 其中这个界面看上去十分简洁 这里自己就记录和分享一下搭建过程 官方网站 Home Homarr Docs 个人环境 支持docke
  • violin plot 小提琴图 matlab R语言 Python

    最近用到violin图 在此总结制作此图的步骤 matlab 需先下载函数文件 https ww2 mathworks cn matlabcentral fileexchange 45134 violin plot 函数中有默认添加 中位数

随机推荐

  • GDB调试详解

    文章目录 调试信息 启动调试 调试进程 调试core文件 GDB调试命令 run continue break backtrace 与 frame info break enable disable delete list print pt
  • 基于深度学习的人脸表情识别开发

    目前深度学习很流行 很大程度减轻了图像开发的难度 表情识别是图像算法的重要研究方向 本文提供一种基于深度学习的表情识别方法 1 获取模型 深度学习的框架比较多 有TF CAFFE PYTORCH KERAS等 然后有很多网络比如resnet
  • 2022年度【产业数字化金铲奖】重磅来袭!

    出品 产业家 第二届金铲奖来了 过去的一年时间里 产业家清晰地看到 数实融合的潮水更加汹涌澎湃且势不可挡 越来越多的企业开始寻求数字化转型 它们来自金融 工业 农业 医疗 能源等等 产业数字化 已经成为当代中国的主旋律 在新的主旋律中 被看
  • OpenWrt之时区设置(夏令时设置)

    今天遇到一个客户关于设置时区问题 涉及到夏令时区 查阅一些资料终于搞明白了 记录如下 因为openwrt是基于linux内核 所以记录一下Linux的时间和时区设置 Linux的时间和时区设置 在linux中与时间相关的文件有 etc lo
  • 如何使用eclipse软件创建一个Java项目?

    同学们在参加Java的时候老师肯定会教给你们如何去创建一个项目 这里怕有些同学没记住 所以单独为大家分享一篇如何使用eclipse软件创建一个Java项目教程 感觉有用的话收藏转发一下 eclipse创建Java项目教程 1 首先我们需要打
  • 将一个Android项目作为另一个Android Library给其他项目使用

    一 eclipse中的使用 开发中如果使用eclipse将一个Android工程作为Android Library给其他项目使用 需要实现的步骤如下 1 将android工程设为库 选择工程右击选择 property gt Android
  • Flutter Plugin调用Native APIs

    关键词 Flutter Flutter Plugin Platform Channel Method Channel Flutter Package Flutter插件 Flutter是Google使用Dart语言开发的一套移动应用开发框架
  • 微信小程序 之 发布流程

    1 前期准备 先想好你的小程序是用来做什么的 是电商 服务预约 知识付费 产品展示 还是团队管理 酒店预订 主要面向的人群都是哪些 现在小程序类型繁多 你一定要对自己有清晰的定位 明确的目标 才能避免把小程序做得乱七八糟 让自己的小程序真正
  • 菜鸟操作:QString和QMap转化(QMap嵌套QMap)

    学习QT的时候遇到一个问题 我想要将QMap转成QString 用于socket通信 查了网上找不到我想到的效果 然后就用一个比较粗糙的做法来实现 以下代码是对于二级QMap操作的 主要思路 将QMap中的数据全都放到QString中 包括
  • 百度人脸识别模块使用分享

    本文出自APICloud官方论坛 感谢鲍永道的分享 首先介绍下百度人脸识别模块 baiduFaceRec baiduFaceRec模块封装了百度AI人脸识别功能 使用此模块可实现百度人脸检测 包括age beauty expression
  • DHT11解析

    一 DHT11工作原理 1 获取数据 DHT11包括一个电阻式感湿元件和一个NTC测温元件 这两个获取温湿度数据的方式都差不多 利用湿 温 敏元件的电气特性 如电阻值 随湿 温 度的变化而变化的原理进行湿 温 度测量 2 数据发送 数据格式
  • SPECjvm 2008 小记

    背景 specjvm2008是免费的 直接官网下载就可以开跑了 但俗话说的好 便宜无好货 没啥厂家买账 看官网列出的成绩公示结果 根本没几家上传成绩 另外 SPECjvm2008本身是测试JRE的执行成绩 也就是java客户端的运行成绩 但
  • IOC的两种容器对比

    Spring的IOC容器是一个提供IOC支持的轻量级容器 Spring提供了两种容器类型 BeanFactory和ApplicationContext BeanFactory 基础类型IOC容器 提供完整的IOC支持 默认采用延迟初始化策略
  • 让Python在退出时强制运行一段代码

    atexit介绍 python atexit 模块定义了一个 register 函数 用于在 python 解释器中注册一个退出函数 这个函数在解释器正常终止时自动执行 一般用来做一些资源清理的操作 atexit 按注册的相反顺序执行这些函
  • qwt之鼠标移动和滚轮滚动

    一 qwt中的鼠标左键平移 主要通过 QwtPlotPanner panner new QwtPlotPanner ui gt qwtPlot gt canvas 这种状态下默认的是鼠标拖动图形 x轴和y轴都可以进行移动 以下实现禁止x轴拖
  • MongoDB快速入门

    一 MongoDB安装配置 1 MongoDB简介 MongoDB 由 databases 组成 databases 由 collections 组成 collections 由documents 相当于行 组成 而documents有fi
  • matlab怎么导出矩阵,如何用matlab 生成矩阵

    随便敲了些和lz类似的关系数字 把你的数字放到这个txt文件里就可以了 比如你有一个txt文件叫numbers txt 里头的数字如下 2 3 1 3 4 1 3 9 1 10 9 1 4 6 1 9 6 1 8 10 1 程序如下 cle
  • 全排列的价值 python实现 蓝桥杯 2137

    问题描述 对于一个排列 A a1 a2 an 定义价值 ci 为 a1 至 ai 1 中小于 ai 的数 的个数 即 ci aj j
  • AI大语言模型时代构建全新数据平台

    在大语言模型的引领下 数据平台领军企业 Databricks 和 Snowflake 的未来重置 探讨了 Databricks 和 Snowflake 等知名平台 存储领域的 Delta udi Iceberg 还是实时化数据处理领域的 D
  • 双向链表的创建以及增删改查

    实现起来其实不难 于是我把代码做了优化 模仿了stm32的库函数哈哈哈 便于理解和修改 不足之处请指出 include stdio h include stdlib h 宏定义 define ElementType int define u