关键词搜索

源码搜索 ×
×

线性表之双向带头循环链表

发布2022-03-22浏览840次

详情内容

准备工作:

创建结构体指针

  1. typedef int LTDataType;
  2. typedef struct ListNode
  3. {
  4. LTDataType data;
  5. struct ListNode* next;
  6. struct ListNode* prev;
  7. }LTNode;

1.创建一个新的节点

基本思路:malloc节点,判断节点是否创造成功。

  1. LTNode* BuyLTNode(LTDataType x)
  2. {
  3. LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));//动态开辟节点
  4. if (newnode == NULL)//判断是否malloc成功
  5. {
  6. printf("malloc fail\n");
  7. exit(-1);//退出程序
  8. }
  9. newnode->data = x;//初始化
  10. newnode->next = NULL;//置空
  11. newnode->prev = NULL;//置空
  12. return newnode;
  13. }

2.尾插

基本思路:1)创建一个新节点

2)找到尾节点,链接即可

画图:

代码:

  1. void LTNodePushBack(LTNode* phead, LTDataType x)
  2. {
  3. assert(phead);
  4. //创建一个新节点
  5. LTNode* newnode = BuyLTNode(x);
  6. //链接节点
  7. LTNode* tail = phead->prev;//找尾节点
  8. tail->next = newnode;
  9. newnode->prev = tail;
  10. newnode->next = phead;
  11. phead->prev = newnode;
  12. }

3.头插

基本思路:1)创建一个新节点

2)找到第一个节点,链接节点

画图:

代码:

  1. void LTNodePushFront(LTNode* phead, LTDataType x)
  2. {
  3. assert(phead);
  4. LTNode* newnode = BuyLTNode(x);
  5. LTNode* first = phead->next;//找到第一个节点
  6. //链接
  7. newnode->next = first;
  8. first->prev = newnode;
  9. phead->next = newnode;
  10. newnode->prev = phead;
  11. }

3.打印链表

基本思路:1)断言

2)创立cur节点,指向第一个节点

3)当cur == phead时,一轮结束。

画图:

代码:

  1. void LTNodePrint(LTNode* phead)
  2. {
  3. LTNode* cur = phead->next;//一般情况下,不允许动头节点
  4. while (cur != phead)//当指向phead时,循环结束
  5. {
  6. printf("%d ", cur->data);
  7. cur = cur->next;//更新cur
  8. }
  9. printf("\n\n");
  10. }

4.尾删

基本思路:1)断言

2)找到尾节点和倒数第二个节点,链接phead与tailPrev,free节点

画图:

代码:

  1. void LTNPopBack(LTNode* phead)
  2. {
  3. //断言
  4. assert(phead);
  5. //找到尾节点和第二个尾节点
  6. LTNode* tail = phead->prev;
  7. LTNode* tailPrev = tail->prev;
  8. //释放尾节点
  9. free(tail);
  10. tail = NULL;
  11. //新的链接
  12. tailPrev->next = phead;
  13. phead->prev = tailPrev;
  14. }

 

5.头删

基本思路:1)断言

2)找到第一个和第二个节点,链接phead和第二个节点,free第一个节点

画图:

代码:

  1. void LTNPopFront(LTNode* phead)
  2. {
  3. //断言
  4. assert(phead);
  5. //找到第一个节点和第二个节点
  6. LTNode* first = phead->next;
  7. LTNode* second = first->next;
  8. //释放内存
  9. free(first);
  10. first = NULL;
  11. //链接
  12. phead->next = second;
  13. second->prev = phead;
  14. }

 

6.找到pos的值

基本思路:1)断言

2)遍历链表,找到就返回链表,找不到就返回NULL

代码:

  1. LTNode* LTNFind(LTNode* phead, LTDataType x)
  2. {
  3. //断言
  4. assert(phead);
  5. //创立一个节点
  6. LTNode* cur = phead->next;
  7. while (cur != phead)
  8. {
  9. if (cur->data == x)
  10. {
  11. //找到返回节点
  12. return cur;
  13. }
  14. cur = cur->next;
  15. }
  16. //找不到,返回NULL
  17. return NULL;
  18. }

7.在pos前插入新节点

基本思路:1)断言

2)创建一个新的节点,找到pos前的节点

3)链接newnode pos和pos的前一个

画图:

代码:

  1. void LTNInsert(LTNode* pos, LTDataType x)
  2. {
  3. //断言
  4. assert(pos);
  5. //找到pos的前一个节点
  6. LTNode* prev = pos->prev;
  7. //创建一个新节点
  8. LTNode* newnode = BuyLTNode(x);
  9. prev->next = newnode;
  10. newnode->prev = prev;
  11. newnode->next = pos;
  12. pos->prev = newnode;
  13. }

 

8.删除pos节点

基本思路:1)断言

2)创建pos前后两个节点,链接,free掉pos节点

画图:

代码:

  1. void LTNErase(LTNode* pos)
  2. {
  3. //断言
  4. assert(pos);
  5. //创建pos对应前后的节点
  6. LTNode* prev = pos->prev;
  7. LTNode* next = pos->next;
  8. //释放节点
  9. free(pos);
  10. pos = NULL;
  11. //链接
  12. prev->next = next;
  13. next->prev = prev;
  14. }

9.销毁链表

基本思路:1)断言

2)创建cur指针记录

3)循环一次,一个节点一个节点释放。

4)phead最后释放,并置空。

代码:

  1. void LTNDestroy(LTNode* phead)
  2. {
  3. //断言
  4. assert(phead);
  5. //创建cur指针
  6. LTNode* cur = phead->prev;
  7. //循环
  8. while (cur != phead)
  9. {
  10. //记录下一个节点
  11. LTNode* next = cur->next;
  12. free(cur);
  13. //更新
  14. cur = next;
  15. }
  16. //释放并置空
  17. free(phead);
  18. phead = NULL;
  19. }

头文件:

  1. #include<stdio.h>
  2. #include<assert.h>
  3. #include<stdlib.h>
  4. //双向带头循环链表
  5. typedef int LTDataType;
  6. typedef struct ListNode
  7. {
  8. LTDataType data;
  9. struct ListNode* next;
  10. struct ListNode* prev;
  11. }LTNode;
  12. //尾插
  13. void LTNodePushBack(LTNode* phead, LTDataType x);
  14. LTNode* BuyLTNode(LTDataType x);
  15. void LTNodePrint(LTNode* phead);
  16. LTNode* LTNodeInit();
  17. //头插
  18. void LTNodePushFront(LTNode* phead, LTDataType x);
  19. //尾删
  20. void LTNPopBack(LTNode* phead);
  21. //头删
  22. void LTNPopFront(LTNode* phead);
  23. //查找
  24. LTNode* LTNFind(LTNode* phead, LTDataType x);
  25. //在pos前面插入
  26. void LTNInsert(LTNode* pos, LTDataType x);
  27. //删除pos位置对应的值
  28. void LTNErase(LTNode* pos);
  29. //销毁链表
  30. void LTNDestroy(LTNode* phead);

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载