【数据结构】循环链表API及实现(二)

简介: 【数据结构】循环链表API及实现

删除结点并返回被删除结点

  • 函数功能:按位置删除一个结点并返回该结点
  • 函数参数:list 循环链表句柄 pos 要删除的链表结点位置
  • 函数返回:被删除的结点
1. CircleListNode* CircleList_Delete(CircleList* list, int pos)
2. {
3.  int i = 0;
4.  CircleListHead* pHead = NULL;
5.  CircleListNode* pCurrent = NULL;
6.  CircleListNode* pLast = NULL;
7.  CircleListNode* pTemp = NULL;
8.  if ((list == NULL) || (pos < 0))
9.  {
10.     printf("err: (list == NULL) || (pos < 0)\n");
11.     return NULL;
12.   }
13.   pHead = (CircleListHead*)list;
14.   pCurrent = &(pHead->head);
15.   for (i = 0; i < pos; i++)
16.   {
17.     pCurrent = pCurrent->next;
18.   }
19.   //如果删除0位置元素,需要获取尾部元素
20.   if (pos == 0)
21.   {
22.     pLast = CircleList_Get(list, pHead->length - 1); //和插入相反,应该先获取尾部元素,再lenth--
23.   }
24.   //先获取pLast,再进行删除操作,否则获取的就不是本来的尾部元素了
25.   pTemp = pCurrent->next;
26.   pCurrent = pTemp->next;
27.   pHead->length--;
28.   if (pLast != NULL)
29.   {
30.     //pLast == NULL说明本身链表为空,只有一个链表头,0号位置为NULL
31.     //不为空,就把尾结点指针域指向现在的0号结点
32.     pLast->next = pTemp->next;
33.   }
34.   if (pHead->length == 0)
35.   {
36.     //删除一个结点后,链表为空
37.     pHead->head.next = NULL;
38.     pHead->slider = NULL;
39.   }
40.   if (pTemp == pHead->slider)
41.   {
42.     //游标元素被删,游标下移
43.     pHead->slider = pTemp->next;
44.   }
45.   return pTemp;
46. }

删除元素示意图

(1)普通位置删除

(2)尾部删除

(3)头部删除

对于前两种情况,删除结点需要借助两个辅助指针,一个pCurrent指示当前结点,其作用类似于插入节点中的pCurrent,另一个pTemp用于保存被删除结点,删除时,只需要pCurrent的指针域指向pTemp指针域的内容即可完成删除,和普通链表删除元素的操作一样。对于第三中情况,需要借助第三个辅助指针pLast,因为要形成环,所以删除0号结点后,要求出原来的尾部元素(删除元素前的尾部元素,而不是删除元素后的尾部元素,这是有本质区别的,详情可见代码中的注释),把原来的尾部元素,指向删除后的0号元素,也就是删除前的1号元素,所以需要一个辅助指针pLast来指向原来的尾部元素。

按结点删除元素

  • 函数功能:按结点删除一个结点并返回该结点
  • 函数参数:list 循环链表句柄 node要删除的链表结点元素
  • 函数返回:被删除的结点
1. CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node)
2. {
3.  int i = 0;
4.  CircleListHead* pHead = NULL;
5.  CircleListNode* pCurrent = NULL;
6.  CircleListNode* pTemp = NULL;
7.  if ((list == NULL) || (node == NULL))
8.  {
9.    printf("err: (list == NULL) || (node == NULL)\n");
10.     return NULL;
11.   }
12.   pHead = (CircleListHead*)list;
13.   pCurrent = &(pHead->head);
14.   for (i = 0; i < pHead->length; i++)
15.   {
16.     if (pCurrent == node)
17.     {
18.       pTemp = pCurrent;
19.       break;
20.     }
21.     pCurrent = pCurrent->next;
22.   }
23.   if (pTemp != NULL)
24.   {
25.     CircleList_Delete(list, i - 1);
26.   }
27.   return pTemp;
28. }

重置游标

  • 函数功能:将游标指向第一个元素
  • 函数参数:list 循环链表句柄
  • 函数返回:游标位置
1. CircleListNode* CircleList_Reset(CircleList* list)
2. {
3.  CircleListHead* pHead = NULL;
4.  if (list == NULL)
5.  {
6.    printf("list == NULL\n");
7.    return NULL;
8.  }
9.  pHead = (CircleListHead*)list;
10.   pHead->slider = pHead->head.next;
11.   return pHead->slider;
12. }

返回当前游标

  • 函数功能:获取游标当前指向的结点
  • 函数参数:list 循环链表句柄
  • 函数返回:游标位置
1. CircleListNode* CircleList_Current(CircleList* list)
2. {
3.  if (list == NULL)
4.  {
5.    printf("list == NULL\n");
6.    return NULL;
7.  }
8.  return ((CircleListHead*)list)->slider;
9. }

游标下移

  • 函数功能:获取游标当前指向的结点,并将游标下移
  • 函数参数:list 循环链表句柄
  • 函数返回:下移前的游标位置
1. CircleListNode* CircleList_Next(CircleList* list)
2. {
3.  CircleListNode* pTemp = NULL;
4.  if (list == NULL)
5.  {
6.    printf("err: (list == NULL)\n");
7.    return NULL;
8.  }
9.  pTemp = ((CircleListHead*)list)->slider;
10.   ((CircleListHead*)list)->slider = pTemp->next;
11.   return pTemp;
12. }

测试函数

1. #include "CircleList.h"
2. 
3. typedef struct MyData
4. {
5.  CircleListNode* node;
6.  int data;
7. }MyData;
8. 
9. int main()
10. {
11.   int i = 0;
12.   int ret = 0;
13.   MyData m[10];
14.   CircleList* mList = NULL;
15. 
16.   for (i = 0; i < 10; i++)
17.   {
18.     m[i].data = i + 1;
19.   }
20. 
21.   mList = CircleList_Create();
22.   if (mList == NULL)
23.   {
24.     ret = -1;
25.     printf("CircleList_Create() err: %d\n", ret);
26.     return -1;
27.   }
28. 
29.   printf("链表长度:");
30.   for (i = 0; i < 10; i++)
31.   {
32.     ret = CircleList_Insert(mList, (CircleListNode*)&m[i], 0);
33.     if (ret != 0)
34.     {
35.       ret = -2;
36.       printf("CircleList_Insert() err: %d\n", ret);
37.       return ret;
38.     }
39.     printf("%d ", CircleList_Length(mList));
40.   }
41.   printf("\n");
42. 
43.   for (i = 0; i < 20; i++)
44.   {
45.     if ((i == 0) || (i == 10))
46.     {
47.       printf("\n循环链表内容:");
48.     }
49.     printf("%d ", ((MyData*)(CircleList_Get(mList, i)))->data);
50.   }
51. 
52.   for (i = 0; i < 10; i++)
53.   {
54.     CircleList_Delete(mList, 0);
55.   }
56. 
57.   printf("\n当前长度:%d \n", CircleList_Length(mList));
58.   CircleList_Destroy(mList);
59. 
60.   system("pause");
61.   return ret;
62. }

具体代码资源已上传,可在下面的链接免费下载

image.png

相关文章
|
2月前
|
存储 算法 Perl
数据结构实验之链表
本实验旨在掌握线性表中元素的前驱、后续概念及链表的建立、插入、删除等算法,并分析时间复杂度,理解链表特点。实验内容包括循环链表应用(约瑟夫回环问题)、删除单链表中重复节点及双向循环链表的设计与实现。通过编程实践,加深对链表数据结构的理解和应用能力。
65 4
|
10天前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
71 5
|
2月前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
116 4
|
2月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
2月前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
2月前
|
算法
数据结构之购物车系统(链表和栈)
本文介绍了基于链表和栈的购物车系统的设计与实现。该系统通过命令行界面提供商品管理、购物车查看、结算等功能,支持用户便捷地管理购物清单。核心代码定义了商品、购物车商品节点和购物车的数据结构,并实现了添加、删除商品、查看购物车内容及结算等操作。算法分析显示,系统在处理小规模购物车时表现良好,但在大规模购物车操作下可能存在性能瓶颈。
53 0
|
3月前
|
存储 Java
数据结构第三篇【链表的相关知识点一及在线OJ习题】
数据结构第三篇【链表的相关知识点一及在线OJ习题】
34 7
|
3月前
|
存储 安全 Java
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
30 3
|
3月前
|
算法 Java
数据结构与算法学习五:双链表的增、删、改、查
双链表的增、删、改、查操作及其Java实现,并通过实例演示了双向链表的优势和应用。
30 0
数据结构与算法学习五:双链表的增、删、改、查