• 初阶数据结构学习记录——다섯 双向循环链表


    目录

    双向链表.h

    双向链表.c

    test.c


    之前写少了一个东西——哨兵位,它是先建立一个节点,然后next指向空,之后在next指向的位置开始插入,也就是next = newhead,哨兵位用在尾插上是比较合适的。

    进入正题

    学了单链表后,双向循环链表就会变得简单。虽然结构稍复杂一点,但实际操作轻松不少。

    双向链表.h

    1. #pragma once
    2. #define  _CRT_SECURE_NO_WARNINGS 1
    3. #include
    4. #include
    5. #include
    6. #include
    7. typedef int LTDataType;
    8. typedef struct ListNode
    9. {
    10.     struct ListNode* prev;
    11.     struct ListNode* next;
    12.     LTDataType data;
    13. }LTNode;
    14. LTNode* BuyListNode(LTDataType x);
    15. LTNode* LTInit();
    16. void LTPrint(LTNode* phead);
    17. //尾插尾删
    18. void LTPushBack(LTNode* phead, LTDataType x);
    19. void LTPopBack(LTNode* phead);
    20. //头插头删
    21. void LTPushFront(LTNode* phead, LTDataType x);
    22. void LTPopFront(LTNode* phead);
    23. LTNode* LTFind(LTNode* phead, LTDataType x);
    24. //在pos之前插入
    25. void LTInsert(LTNode* pos, LTDataType x);
    26. //删除pos位置
    27. void LTErase(LTNode* pos);
    28. bool LTEmpty(LTNode* phead);
    29. size_t LTSize(LTNode* phead);
    30. void LTDestroy(LTNode* phead);

    双向链表.c

    1. LTNode* BuyListNode(LTDataType x)
    2. {
    3. LTNode* node = (LTNode*)malloc(sizeof(LTNode));
    4. if (node == NULL)
    5. {
    6. perror("malloc fail");
    7. exit(-1);
    8. }
    9. node->data = x;
    10. node->next = NULL;
    11. node->prev = NULL;
    12. return node;
    13. }
    14. LTNode* LTInit()
    15. {
    16. LTNode* phead = BuyListNode(-1);
    17. phead->next = phead;
    18. phead->prev = phead;
    19. return phead;
    20. }
    21. void LTPrint(LTNode* phead)
    22. {
    23. assert(phead);
    24. LTNode* cur = phead->next;
    25. while (cur != phead)
    26. {
    27. printf("%d ", cur->data);
    28. cur = cur->next;
    29. }
    30. printf("\n");
    31. }
    32. void LTPushBack(LTNode* phead, LTDataType x)
    33. {
    34. assert(phead);
    35. /*LTNode* newnode = BuyListNode(x);
    36. LTNode* tail = phead->prev;
    37. tail->next = newnode;
    38. newnode->prev = tail;
    39. newnode->next = phead;
    40. phead->prev = newnode;*/
    41. LTInsert(phead, x);
    42. }
    43. void LTPopBack(LTNode* phead)
    44. {
    45. assert(phead);
    46. assert(phead->next != phead); // 空
    47. //LTNode* tail = phead->prev;
    48. //LTNode* tailPrev = tail->prev;
    49. //tailPrev->next = phead;
    50. //phead->prev = tailPrev;
    51. //free(tail);
    52. LTErase(phead->prev);
    53. }
    54. void LTPushFront(LTNode* phead, LTDataType x)
    55. {
    56. assert(phead);
    57. /*LTNode* newnode = BuyListNode(x);
    58. newnode->next = phead->next;
    59. phead->next->prev = newnode;
    60. phead->next = newnode;
    61. newnode->prev = phead;*/
    62. //LTNode* newnode = BuyListNode(x);
    63. //LTNode* first = phead->next;
    64. phead newnode first
    65. 顺序无关
    66. //phead->next = newnode;
    67. //newnode->prev = phead;
    68. //newnode->next = first;
    69. //first->prev = newnode;
    70. LTInsert(phead->next, x);
    71. }
    72. void LTPopFront(LTNode* phead)
    73. {
    74. assert(phead);
    75. assert(phead->next != phead); // 空
    76. /*LTNode* first = phead->next;
    77. LTNode* second = first->next;
    78. free(first);
    79. phead->next = second;
    80. second->prev = phead;*/
    81. LTErase(phead->next);
    82. }
    83. LTNode* LTFind(LTNode* phead, LTDataType x)
    84. {
    85. assert(phead);
    86. LTNode* cur = phead->next;
    87. while (cur != phead)
    88. {
    89. if (cur->data == x)
    90. {
    91. return cur;
    92. }
    93. cur = cur->next;
    94. }
    95. return NULL;
    96. }
    97. // 在pos之前插入x
    98. void LTInsert(LTNode* pos, LTDataType x)
    99. {
    100. assert(pos);
    101. LTNode* prev = pos->prev;
    102. LTNode* newnode = BuyListNode(x);
    103. // prev newnode pos
    104. prev->next = newnode;
    105. newnode->prev = prev;
    106. newnode->next = pos;
    107. pos->prev = newnode;
    108. }
    109. // 删除pos位置
    110. void LTErase(LTNode* pos)
    111. {
    112. assert(pos);
    113. LTNode* prev = pos->prev;
    114. LTNode* next = pos->next;
    115. free(pos);
    116. prev->next = next;
    117. next->prev = prev;
    118. }
    119. bool LTEmpty(LTNode* phead)
    120. {
    121. assert(phead);
    122. /*if (phead->next == phead)
    123. {
    124. return true;
    125. }
    126. else
    127. {
    128. return false;
    129. }*/
    130. return phead->next == phead;
    131. }
    132. size_t LTSize(LTNode* phead)
    133. {
    134. assert(phead);
    135. size_t size = 0;
    136. LTNode* cur = phead->next;
    137. while (cur != phead)
    138. {
    139. ++size;
    140. cur = cur->next;
    141. }
    142. return size;
    143. }
    144. void LTDestroy(LTNode* phead)
    145. {
    146. assert(phead);
    147. LTNode* cur = phead->next;
    148. while (cur != phead)
    149. {
    150. LTNode* next = cur->next;
    151. free(cur);
    152. cur = next;
    153. }
    154. free(phead);
    155. //phead = NULL;
    156. }

    test.c

    1. void TestList1()
    2. {
    3.     LTNode* phead = BuyListNode(-1);
    4.     phead->prev = phead;
    5.     phead->next = phead;
    6.     //没有办法LTNode* phead = LTInit(phead), 总是在说使用未初始化的变量,嗯,毛病太多了
    7.     LTPushBack(phead, 1);
    8.     LTPushBack(phead, 2);
    9.     LTPushBack(phead, 3);
    10.     LTPushBack(phead, 4);
    11.     LTPrint(phead);
    12. LTPopBack(phead);
    13. LTPrint(phead);
    14. LTPopBack(phead);
    15. LTPrint(phead);
    16. LTPopBack(phead);
    17. LTPrint(phead);
    18. LTPopBack(phead);
    19. LTPrint(phead);
    20. }
    21. void TestList2()
    22. {
    23.     LTNode* phead = BuyListNode(-1);
    24.     phead->prev = phead;
    25.     phead->next = phead;
    26.     LTPushFront(phead, 1);
    27.     LTPushFront(phead, 2);
    28.     LTPushFront(phead, 3);
    29.     LTPushFront(phead, 4);
    30.     LTPrint(phead);
    31.     LTPopFront(phead);
    32.     LTPrint(phead);
    33.     LTPopFront(phead);
    34.     LTPrint(phead);
    35.     LTPopFront(phead);
    36.     LTPrint(phead);
    37.     LTPopFront(phead);
    38.     LTPrint(phead);
    39. }
    40. void TestList3()
    41. {
    42. LTNode* phead = BuyListNode(-1);
    43. phead->prev = phead;
    44. phead->next = phead;
    45. LTPushFront(phead, 1);
    46. LTPushFront(phead, 2);
    47. LTPushFront(phead, 3);
    48. LTPushFront(phead, 4);
    49. LTPrint(phead);
    50. LTNode* pos = LTFind(phead, 3);
    51. if (pos)
    52. {
    53. pos->data *= 10;
    54. }
    55. LTPrint(phead);
    56. LTDestroy(phead);
    57. phead = NULL;
    58. }
    59. int main()
    60. {
    61. TestList3();
    62. return 0;
    63. }

    其实是觉得没什么细讲的,就只发了代码。

    结束。

  • 相关阅读:
    uniapp 实现在线签合同/签名/信息认证(无插件依赖)
    uni-App获取地图address与高德地图API配合
    ffmpeg ffplay 基于h264中SEI信息进行双摄画面拆分播放实践
    Pyside6 QFile
    中国SaaS行业等待“渡劫时刻”
    Git常用命令汇总
    设计一个简单的通讯录
    发送注册连接到 FreeSWITCH 服务器的客户端
    【广州华锐互动】鱼类授精繁殖VR虚拟仿真实训系统
    Python类练习
  • 原文地址:https://blog.csdn.net/kongqizyd146/article/details/127749630