• 数据结构之双向带头循环链表函数功能实现与详细解析


    个人主页点我进入主页

    专栏分类:C语言初阶      C语言程序设计————KTV       C语言小游戏     C语言进阶

    C语言刷题       数据结构初阶

    欢迎大家点赞,评论,收藏。

    一起努力,一起奔赴大厂。

    目录

    1.前言

    2.带头双向循环链表函数实现

    3.总结


    1.前言

            在前面我们写过单链表,循环链表的博客,今天我主要给大家来带关于双向带头循环链表函数的功能与实现,双向带头循环链表相对于单链表,循环链表非常的容易实现,他的函数的功能和 单链表,循环链表一样,如果你想要快速实现一个链表的所有功能,带头双向循环链表非常的容易,接下来让我们看看带头双向链表的奥妙把,看完你绝对会佩服写出这种结构的人。

    2.带头双向循环链表函数实现

    1. #include
    2. #include
    3. #include
    4. typedef struct ListNode {
    5. int data;
    6. struct ListNode* prev, * next;
    7. }ListNode;
    8. ListNode* ListCreate(int x)
    9. {
    10. ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
    11. if (newnode == NULL)
    12. {
    13. perror("malloc");
    14. return NULL;
    15. }
    16. newnode->next = NULL;
    17. newnode->prev = NULL;
    18. newnode->data = x;
    19. return newnode;
    20. }
    21. ListNode* LInit()
    22. {
    23. ListNode* head = ListCreate(-1);
    24. head->next = head;
    25. head->prev = head;
    26. return head;
    27. }
    28. void ListDestory(ListNode* phead)
    29. {
    30. assert(phead);
    31. ListNode* cur = phead->next, * prev = phead;
    32. while (prev != phead)
    33. {
    34. free(prev);
    35. prev = cur;
    36. cur = cur->next;
    37. }
    38. }
    39. void ListPrint(ListNode* phead)
    40. {
    41. assert(phead);
    42. ListNode* cur = phead->next;
    43. printf("哨兵位<=>");
    44. while (cur != phead)
    45. {
    46. printf("%d<=>", cur->data);
    47. cur = cur->next;
    48. }
    49. printf("\n");
    50. }
    51. void ListPushBack(ListNode* phead, int x)
    52. {
    53. assert(phead);
    54. ListNode* newnode = ListCreate(x);
    55. ListNode* tail = phead->prev;
    56. tail->next = newnode;
    57. newnode->prev = tail;
    58. newnode->next = phead;
    59. phead->prev = newnode;
    60. }
    61. void ListPushFrount(ListNode* phead, int x)
    62. {
    63. assert(phead);
    64. ListNode* newnode = ListCreate(x);
    65. ListNode* cur = phead->next;
    66. phead->next = newnode;
    67. newnode->prev = phead;
    68. newnode->next = cur;
    69. cur->prev = newnode;
    70. }
    71. void ListPopBack(ListNode* phead)
    72. {
    73. assert(phead && phead->next != phead);
    74. ListNode* cur = phead->prev;
    75. cur->prev->next = phead;
    76. phead->prev = cur->prev;
    77. free(cur);
    78. }
    79. void ListPopFrount(ListNode* phead)
    80. {
    81. assert(phead && phead->next != phead);
    82. ListNode* cur = phead->next;
    83. phead->next = cur->next;
    84. cur->next->prev = phead;
    85. free(cur);
    86. }
    87. ListNode* ListFind(ListNode* phead, int x)
    88. {
    89. assert(phead);
    90. ListNode* cur = phead->next;
    91. while (cur->data != x)
    92. {
    93. cur = cur->next;
    94. }
    95. return cur;
    96. }
    97. void ListInsert(ListNode* pos, int x)
    98. {
    99. assert(pos);
    100. ListNode* newnode = ListCreate(x);
    101. ListNode* cur = pos->prev;
    102. cur->next = newnode;
    103. newnode->prev = cur;
    104. newnode->next = pos;
    105. pos->prev = newnode;
    106. }
    107. void ListErase(ListNode* pos)
    108. {
    109. assert(pos);
    110. ListNode* cur = pos->next;
    111. ListNode* prev = pos->prev;
    112. free(pos);
    113. cur->prev = prev;
    114. prev->next = cur;
    115. }
    116. void text1()
    117. {
    118. ListNode* head = LInit();
    119. ListPushBack(head, 1);
    120. ListPushBack(head, 2);
    121. ListPushBack(head, 3);
    122. ListPushBack(head, 4);
    123. ListPushBack(head, 5);
    124. ListPushFrount(head, 0);
    125. ListPrint(head);
    126. ListPopBack(head);
    127. ListPrint(head);
    128. ListPopBack(head);
    129. ListPrint(head);
    130. ListPopFrount(head);
    131. ListPrint(head);
    132. ListPopFrount(head);
    133. ListPrint(head);
    134. ListPushBack(head, 4);
    135. ListPushBack(head, 5);
    136. ListNode* cur = ListFind(head,3);
    137. ListPushFrount(head, 1);
    138. ListPushFrount(head, 0);
    139. printf("%d\n", cur->data);
    140. ListPrint(head);
    141. ListInsert(head, 10);
    142. ListPrint(head);
    143. }

    3.总结

            带头双向循环的链表非常的好,接下俩我们对顺序表和链表的存储空间,随机访问,任意位置插入或删除元素,插入,缓存利用率,应用场景进行分析

    不同点顺序表链表
    存储空间上物理上一定连续逻辑上连续,但物理上不一定连
    随机访问支持O(1)不支持:O(N)
    任意位置插入或者删除元
    可能需要搬移元素,效率低O(N)只需修改指针指向
    插入动态顺序表,空间不够时需要扩
    没有容量的概念
    应用场景元素高效存储+频繁访问任意位置插入和删除频繁
    缓存利用率

  • 相关阅读:
    记一堂公开课《前端架构的设计与进化》思考总结
    Nature Communications|柔性无感智能隐形眼镜(柔性传感/可穿戴电子/柔性电子)
    浅谈Vue 3的响应式对象: ref和reactive
    Xshell连接Docker版本CentOS7
    Python---函数的应用案例(多个)
    echarts折柱混线图根据后台数据动态刷新显示数据
    1452. 收藏清单-排序+交叠比较-力扣双百代码
    Golang高级数据结构
    如何快速走出网站沙盒期(关于优化百度SEO提升排名)
    基于SSM的车库智能管理平台设计与实现
  • 原文地址:https://blog.csdn.net/Infernal_Puppet/article/details/134495668