请选择 进入手机版 | 继续访问电脑版

双向循环链表的增删查减

[复制链接]
卓小兔 发表于 2021-1-3 11:56:43 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
文章目次



1.链表布局体

  1. typedef int LTDataType;typedef struct ListNode{        struct ListNode *prev;        struct ListNode *next;        LTDataType data;}ListNode;ListNode* ListInit(ListNode *pphead);//初始化ListNode* BuyListNode(LTDataType data);//创建节点void ListInsert(ListNode *pos, LTDataType data);//在pos前面插入ListNode* ListFind(ListNode *pphead, LTDataType data);//寻找节点void ListErase(ListNode *pos);//删除void ListPushBack(ListNode *pphead, LTDataType data);//尾插void ListPushFront(ListNode *pphead, LTDataType data);//头插void ListPopBack(ListNode *pphead);//尾删void ListPopFront(ListNode *pphead);//头删void ListPrint(ListNode *pphead);//打印void ListClear(ListNode *pphead);//清空void ListDestory(ListNode **pphead);//销毁
复制代码
2.链表头的初始化

头的初始化有两种方式,要么传二级指针,要么开辟好空间的节点返回地点;
  1. ListNode* ListInit(ListNode *pphead)//初始化{        /*assert(pphead);                *pphead = (ListNode *)malloc(sizeof(ListNode));        assert(*pphead);                (*pphead)->prev = (*pphead)->next = *pphead;        (*pphead)->data = 0;*/        pphead = (ListNode *)malloc(sizeof(ListNode));        assert(pphead);        pphead->prev =pphead->next = pphead;        pphead->data = 0;        return pphead;}
复制代码
3.节点的创建

  1. ListNode* BuyListNode(LTDataType data)//创建节点{        ListNode *node = (ListNode *)malloc(sizeof(ListNode));        assert(node);        node->next = node->prev = NULL;        node->data = data;        return node;}
复制代码
4.插入

  1. void ListInsert(ListNode *pos,LTDataType data)//早Pos前面插入 {         assert(pos);         ListNode *node = BuyListNode(data);         ListNode *prev = pos->prev;//pos前面的节点        //和pos前面节点链接         prev->next = node;         node->prev = prev;         //和pos链接         node->next = pos;         pos->prev = node; }
复制代码
5.查找

  1. ListNode* ListFind(ListNode *pphead, LTDataType data)//寻找节点 {         assert(pphead);         ListNode *cur = pphead->next;                  while (cur!=pphead)         {                 if (cur->data == data)                         return cur;                 cur = cur->next;         }         return NULL; }
复制代码
6.删除

  1. void ListErase(ListNode *pos)//删除 {         assert(pos);         //pos前后节点         ListNode *prev = pos->prev;         ListNode *next = pos->next;         //前后节点链接         prev->next = next;         next->prev = prev;         free(pos);         pos = NULL;//没有多大意义,因为出了作用域就访问不到了 }
复制代码
7.尾插

尾插除了直接实现,还可以调用前面的插入函数;
双向循环链表头的前面就是尾;
  1. void ListPushBack(ListNode *pphead,LTDataType data)//尾插 {         assert(pphead);         //ListInsert(pphead, data);         ListNode *node = BuyListNode(data);         ListNode *tail = pphead->prev;//最后一个节点         //最后两个节点链接         tail->next = node;         node->prev = tail;         //和头链接         pphead->prev = node;         node->next = pphead;  }
复制代码
8.头插

同理,头插也可以调用插入函数完成;
  1. void ListPushFront(ListNode *pphead, LTDataType data)//头插 {         assert(pphead);         //ListInsert(pphead->next, data);         ListNode *node = BuyListNode(data);         ListNode *next = pphead->next;//未插入前的第一个节点         //插入的接点和背面的举行链接         node->next = next;         next->prev = node;         //头链接         pphead->next = node;         node->prev = pphead; }
复制代码
9.尾删

尾插也可以通过调用删除函数举行;
  1. void ListPopBack(ListNode *pphead)//尾删 {         assert(pphead);         assert(pphead->next != pphead);//头不能删         //ListErase(pphead->prev);         ListNode *tail = pphead->prev;//尾         ListNode *tailPrev = tail->prev;         pphead->prev = tailPrev;         tailPrev->next = pphead;         free(tail); }
复制代码
10.头删

头删同样可以调用删除函数举行;
  1. void ListPopFront(ListNode *pphead)//头删 {         assert(pphead);         assert(pphead->next != pphead);         //ListErase(pphead->next);         ListNode *head= pphead->next;         ListNode *next = head->next;         pphead->next = next;         next->prev = pphead;         free(head); }
复制代码
11.打印

  1. void ListPrint(ListNode *pphead)//打印 {         assert(pphead);         ListNode *cur = pphead->next;         while (cur!=pphead)         {                 printf("%d ", cur->data);                 cur = cur->next;         }         printf("\n"); }
复制代码
12.清空和销毁

清空生存头结点,销毁头结点也要释放,同时要置空;
  1. void ListClear(ListNode *pphead)//清空 {         assert(pphead);         ListNode *cur = pphead->next;         while (cur!=pphead)         {                 ListNode *next = cur->next;                 free(cur);                 cur = next;         }         pphead->prev = pphead->next = pphead;; } void ListDestory(ListNode **pphead)//销毁 {         assert(pphead);         ListClear(*pphead);         free(*pphead);         *pphead = NULL; }
复制代码
来源:https://blog.csdn.net/ych9527/article/details/112003600
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

发布主题

专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )