双向链表的创建以及增删改查
2021/9/26 23:11:13
本文主要是介绍双向链表的创建以及增删改查,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
实现起来其实不难,于是我把代码做了优化,模仿了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); }
这篇关于双向链表的创建以及增删改查的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南