当前位置:   article > 正文

【数据结构】链表

【数据结构】链表
        

      Yan-英杰的主页

 悟已往之不谏 知来者之可追


目录

​编辑 链表的概念及结构

​编辑链表的分类

​编辑单链表的实现


链表的概念及结构

        概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。

       

        

        现实中数据结构中  

链表的分类

        实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:
        
                 1. 单向或者双向
                        

               

                 2. 带头或者不带头

                

                 3. 循环或者非循环

        

       虽然有这么多的链表的结构,但是我们实际中最常用还是两种结构:

        

        1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。
        2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。

单链表的实现

        SList.h

        

  1. #pragma once
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<stdlib.h>
  5. #include<assert.h>
  6. typedef int SLTDataType;
  7. typedef struct SListNode
  8. {
  9. SLTDataType data;
  10. struct SListNode* next;
  11. }SListNode;
  12. // 动态申请一个节点
  13. SListNode* BuySListNode(SLTDataType x);
  14. // 单链表打印
  15. void SListPrint(SListNode* plist);
  16. // 单链表尾插
  17. void SListPushBack(SListNode** pplist, SLTDataType x);
  18. // 单链表的头插
  19. void SListPushFront(SListNode** pplist, SLTDataType x);
  20. // 单链表的尾删
  21. void SListPopBack(SListNode** pplist);
  22. // 单链表头删
  23. void SListPopFront(SListNode** pplist);
  24. // 单链表查找
  25. SListNode* SListFind(SListNode* plist, SLTDataType x);
  26. // 单链表在pos位置之后插入x
  27. // 分析思考为什么不在pos位置之前插入?
  28. void SListInsertAfter(SListNode* pos, SLTDataType x);
  29. // 单链表删除pos位置之后的值
  30. // 分析思考为什么不删除pos位置?
  31. void SListEraseAfter(SListNode* pos);
  32. // 单链表的销毁
  33. void SListDestroy(SListNode* plist);

        SList.c

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include "SList.h"
  3. // 动态申请一个节点
  4. SListNode* BuySListNode(SLTDataType x)
  5. {
  6. SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
  7. if (newnode == NULL)
  8. {
  9. perror("fail:malloc");
  10. }
  11. newnode->data = x;
  12. newnode->next = NULL;
  13. return newnode;
  14. }
  15. //尾插
  16. void SListPushBack(SListNode** pplist, SLTDataType x)
  17. {
  18. assert(pplist);
  19. SListNode * newnode = BuySListNode(x);
  20. if (*pplist == NULL)
  21. {
  22. *pplist = newnode;
  23. }
  24. else
  25. {
  26. SListNode* tail = *pplist;
  27. while (tail->next != NULL)
  28. {
  29. tail = tail->next;
  30. }
  31. tail->next = newnode;
  32. }
  33. }
  34. //尾删
  35. void SListPopBack(SListNode** pplist)
  36. {
  37. assert(pplist);
  38. assert(pplist);
  39. //两种情况
  40. //1>一个节点时
  41. if ((* pplist)->next == NULL)
  42. {
  43. free(*pplist);
  44. *pplist = NULL;
  45. }
  46. //2>多个节点时
  47. else
  48. {
  49. SListNode* tail = *pplist;
  50. while (tail->next->next != NULL)
  51. {
  52. tail = tail->next;
  53. }
  54. free(tail->next);
  55. tail->next = NULL;
  56. }
  57. }
  58. //头插
  59. void SListPushFront(SListNode** pplist, SLTDataType x)
  60. {
  61. assert(pplist);
  62. SListNode* phead = BuySListNode(x);
  63. phead->next = *pplist;
  64. *pplist = phead;
  65. }
  66. //头删
  67. void SListPopFront(SListNode** pplist)
  68. {
  69. assert(pplist);
  70. assert(*pplist);
  71. SListNode* phead = (* pplist)->next;
  72. *pplist = phead;
  73. }
  74. //打印单链表
  75. void SListPrint(SListNode* plist)
  76. {
  77. SListNode* cur = plist;
  78. while (cur)
  79. {
  80. printf("%d->",cur->data);
  81. cur = cur->next;
  82. }
  83. printf("NULL");
  84. }
  85. SListNode* SListFind(SListNode* plist, SLTDataType x)
  86. {
  87. SListNode* cur = plist;
  88. while (cur)
  89. {
  90. if (cur->data == x)
  91. {
  92. return cur;
  93. }
  94. cur = cur->next;
  95. }
  96. return NULL;
  97. }
  98. void SListInsertAfter(SListNode* pos, SLTDataType x)
  99. {
  100. assert(pos);
  101. SListNode* newnode = BuySListNode(x);
  102. newnode->next = pos->next;
  103. pos->next = newnode;
  104. }
  105. void SListEraseAfter(SListNode* pos)
  106. {
  107. assert(pos);
  108. assert(pos->next);
  109. SListNode* del = pos->next;
  110. pos->next = del->next;
  111. free(del);
  112. del = NULL;
  113. }
  114. // 单链表的销毁
  115. void SListDestroy(SListNode** plist)
  116. {
  117. free(*plist);
  118. *plist = NULL;
  119. }

        test.c

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include "SList.h"
  3. void TestSList()
  4. {
  5. SListNode* SList = NULL;
  6. SListPushBack(&SList, 1);
  7. SListPushBack(&SList, 2);
  8. SListPushBack(&SList, 3);
  9. SListPushBack(&SList, 4);
  10. SListPopBack(&SList);
  11. SListPushFront(&SList,5);
  12. SListPopFront(&SList);
  13. SListDestroy(&SList);
  14. SListPrint(SList);
  15. }
  16. int main()
  17. {
  18. TestSList();
  19. return 0;
  20. }

画图思想:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/187320
推荐阅读
相关标签
  

闽ICP备14008679号