当前位置:   article > 正文

C语言初阶数据结构(二)单链表(详细图解,一看就懂)_数据结构流程图

数据结构流程图

目录

一、功能实现(图解)以及效果展示

1.1.定义结构体变量

1.2尾插数据

1.3头插数据

1.4尾删数据

1.5头删数据

1.6查找数据

1.7随机插入数据

1.8随机删除数据

1.9打印数据

二、完整代码


菜单展示

一、功能实现+图解+效果展示

1.首先定义一个结构体变量,成员变量包括数据域和指针域

  1. struct SListNode
  2. {
  3. SLTDataType data;//数据域
  4. struct SListNode* next;//指针域
  5. };

2.尾插数据

首先创建一个新结点,存放要插入的数据

1)如果无头结点,直接将该新结点作为头结点。

2)如果有头结点就需要遍历找为尾结点,然后将新结点插入到尾结点后即可

  1. void SListPushBack(SLTNode* *pphead, SLTDataType x)
  2. {
  3. SLTNode* newnode = BuySListNode(x);
  4. if (*pphead == NULL)
  5. {
  6. *pphead = newnode;
  7. }
  8. //找尾指针
  9. else
  10. {
  11. SLTNode* tail = *pphead;
  12. while (tail->next != NULL)
  13. {
  14. tail = tail->next;
  15. }
  16. //尾结点,链接新结点
  17. tail->next = newnode;
  18. }
  19. }

效果展示

3.头插数据:将新创建的结点作为头结点

  1. void SListPushFront(SLTNode** pphead, SLTDataType x)
  2. {
  3. SLTNode* newnode = BuySListNode(x);
  4. newnode->next = *pphead;
  5. *pphead = newnode;
  6. }

 效果展示

4.尾删数据:

1)如果链表为空,结束操作

2)如果只有头结点,直接删除头结点即可

3) 节点数大于1时,直接遍历找到最后一个结点然后删除即可,最后将倒数第二个结点的指针域为空即可。

  1. void SListPopBack(SLTNode** pphead)
  2. {
  3. //1.如果为空 2.如果只有一个结点 3.正常
  4. if (*pphead == NULL)
  5. {
  6. perror("");
  7. return;
  8. }
  9. else if((*pphead)->next==NULL)
  10. {
  11. free(*pphead);
  12. *pphead = NULL;
  13. }
  14. else
  15. {
  16. SLTNode* pre = NULL;
  17. SLTNode* tail = *pphead;
  18. while (tail->next != NULL)
  19. {
  20. pre = tail;
  21. tail = tail->next;
  22. }
  23. free(tail);
  24. pre->next = NULL;
  25. }
  26. }

效果展示

5.头删数据:

1)如果链表为空,结束操作。

2)如果只有头结点,直接删除头结点即可。

3)结点数大于1时,创建一个新指针str ,使str指向头结点的下一个结点,然后将头结点释放,此时再将str的地址赋给*pphead,使其成为头结点

  1. void SListPopFront(SLTNode** pphead)
  2. {
  3. //1.空 2.正常
  4. if (*pphead == NULL)
  5. {
  6. perror("");
  7. return;
  8. }
  9. else
  10. {
  11. SLTNode* str = (*pphead)->next;
  12. (*pphead)->next = str;
  13. free(*pphead);
  14. *pphead = str;
  15. }
  16. }

效果展示

6.查找数据:(效果展示与7和8搭配使用)

从头结点开始遍历链表,找到就返回结点地址,没找到就返回NULL

  1. SLTNode* SListFind(SLTNode** pphead, SLTDataType x)
  2. {
  3. SLTNode* cur = *pphead;
  4. while (cur != NULL)
  5. {
  6. if (cur->data == x)
  7. {
  8. return cur;
  9. }
  10. cur = cur->next;
  11. }
  12. return NULL;
  13. }

7.随机插入数据:

1.如果想插入元素的位置刚好是头结点,直接调用头插数据即可

 2..如果想插入元素的位置不是头结点,设置一个指针pre去查询想插入数据的位置,当pre->next指向的位置刚好是pos的位置时,将创建好的结点的插入其中即可。

  1. void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
  2. {
  3. if (pos == *pphead)
  4. {
  5. SListPushFront(pphead, x);
  6. }
  7. else
  8. {
  9. SLTNode* newnode = BuySListNode(x);
  10. newnode->next = pos;
  11. SLTNode* pre = *pphead;
  12. while (pre->next != pos)
  13. {
  14. pre = pre->next;
  15. }
  16. pre->next = newnode;
  17. }
  18. }

效果展示

8.随机删除数据

1.如果删除位置刚好是头结点,直接调用头删函数即可

2.如果删除位置不是头结点,设置一个指针pre去查询想删除的位置,当pre->next指向的位置刚好是pos的位置时, 让pre指针域指向pos的后一个位置,然后释放pos即可。

  1. void SListErase(SLTNode** pphead, SLTNode* pos)
  2. {
  3. if (pos == *pphead)
  4. {
  5. SListPopFront(pphead);
  6. }
  7. {
  8. SLTNode* pre = *pphead;
  9. while (pre->next != pos)
  10. {
  11. pre = pre->next;
  12. }
  13. pre->next = pos->next;
  14. free(pos);
  15. pos = NULL;
  16. }
  17. }

效果实现

9.打印单链表:

遍历打印即可

  1. void SListPrint(SLTNode* phead)
  2. {
  3. SLTNode* cur = phead;
  4. while (cur != NULL)
  5. {
  6. printf("%d->", cur->data);
  7. cur = cur->next;
  8. }
  9. printf("NULL\n");
  10. }

二、完整代码

头文件SList.h(函数声明)

  1. #pragma once
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. typedef int SLTDataType;
  5. //链表
  6. struct SListNode
  7. {
  8. SLTDataType data;//数据域
  9. struct SListNode* next;//指针域
  10. };
  11. typedef struct SListNode SLTNode;
  12. //打印功能 不会改变链表的头指针,传一级指针
  13. void SListPrint(SLTNode* phead);
  14. //尾插 头插 尾删 头删 随机插入 随机删除 会改变链表的头指针,传二级指针
  15. void SListPushBack(SLTNode** pphead, SLTDataType x);
  16. void SListPushFront(SLTNode** pphead, SLTDataType x);
  17. void SListPopBack(SLTNode** pphead);
  18. void SListPopFront(SLTNode** pphead);
  19. SLTNode* SListFind(SLTNode** pphead, SLTDataType x);
  20. //在pos的前面插入x
  21. void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
  22. //删除pos位置的值
  23. void SListErase(SLTNode** pphead, SLTNode* pos);

源文件SList.c(函数功能实现)

  1. #include"SList.h"
  2. //打印
  3. void SListPrint(SLTNode* phead)
  4. {
  5. SLTNode* cur = phead;
  6. while (cur != NULL)
  7. {
  8. printf("%d->", cur->data);
  9. cur = cur->next;
  10. }
  11. printf("NULL\n");
  12. }
  13. //创建新结点
  14. SLTNode* BuySListNode(SLTDataType x)
  15. {
  16. SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
  17. newnode->data = x;
  18. newnode->next = NULL;
  19. return newnode;
  20. }
  21. //尾插
  22. void SListPushBack(SLTNode* *pphead, SLTDataType x)
  23. {
  24. SLTNode* newnode = BuySListNode(x);
  25. if (*pphead == NULL)
  26. {
  27. *pphead = newnode;
  28. }
  29. //找尾指针
  30. else
  31. {
  32. SLTNode* tail = *pphead;
  33. while (tail->next != NULL)
  34. {
  35. tail = tail->next;
  36. }
  37. //尾结点,链接新结点
  38. tail->next = newnode;
  39. }
  40. }
  41. //头插
  42. void SListPushFront(SLTNode** pphead, SLTDataType x)
  43. {
  44. SLTNode* newnode = BuySListNode(x);
  45. newnode->next = *pphead;
  46. *pphead = newnode;
  47. }
  48. //尾删
  49. void SListPopBack(SLTNode** pphead)
  50. {
  51. //1.如果为空 2.如果只有一个结点 3.正常
  52. if (*pphead == NULL)
  53. {
  54. perror("");
  55. return;
  56. }
  57. else if((*pphead)->next==NULL)
  58. {
  59. free(*pphead);
  60. *pphead = NULL;
  61. }
  62. else
  63. {
  64. SLTNode* pre = NULL;
  65. SLTNode* tail = *pphead;
  66. while (tail->next != NULL)
  67. {
  68. pre = tail;
  69. tail = tail->next;
  70. }
  71. free(tail);
  72. pre->next = NULL;
  73. }
  74. }
  75. //头删
  76. void SListPopFront(SLTNode** pphead)
  77. {
  78. //1.空 2.正常
  79. if (*pphead == NULL)
  80. {
  81. perror("");
  82. return;
  83. }
  84. else
  85. {
  86. SLTNode* str = (*pphead)->next;
  87. (*pphead)->next = str;
  88. free(*pphead);
  89. *pphead = str;
  90. }
  91. }
  92. //查找数据
  93. SLTNode* SListFind(SLTNode** pphead, SLTDataType x)
  94. {
  95. SLTNode* cur = *pphead;
  96. while (cur != NULL)
  97. {
  98. if (cur->data == x)
  99. {
  100. return cur;
  101. }
  102. cur = cur->next;
  103. }
  104. return NULL;
  105. }
  106. //随机插入
  107. void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
  108. {
  109. if (pos == *pphead)
  110. {
  111. SListPushFront(pphead, x);
  112. }
  113. else
  114. {
  115. SLTNode* newnode = BuySListNode(x);
  116. newnode->next = pos;
  117. SLTNode* pre = *pphead;
  118. while (pre->next != pos)
  119. {
  120. pre = pre->next;
  121. }
  122. pre->next = newnode;
  123. }
  124. }
  125. //随机删除
  126. void SListErase(SLTNode** pphead, SLTNode* pos)
  127. {
  128. if (pos == *pphead)
  129. {
  130. SListPopFront(pphead);
  131. }
  132. {
  133. SLTNode* pre = *pphead;
  134. while (pre->next != pos)
  135. {
  136. pre = pre->next;
  137. }
  138. pre->next = pos->next;
  139. free(pos);
  140. pos = NULL;
  141. }
  142. }

源文件text.c(功能测试)

  1. #include"SList.h"
  2. void menu()
  3. {
  4. printf("*************************************\n");
  5. printf("**1.尾插数据 2.头插数据 \n");
  6. printf("**3.删除尾数据 4.删除首数据\n");
  7. printf("**5.随机插入数据 6.随机删除数据\n");
  8. printf("**7.打印数据 0.退出程序**\n");
  9. printf("*************************************\n");
  10. printf("请输入你的选择:>\n");
  11. }
  12. void Text()
  13. {
  14. int input = 0;
  15. SLTDataType x = 0;
  16. SLTNode* plist = NULL;
  17. do
  18. {
  19. menu();
  20. scanf("%d", &input);
  21. switch (input)
  22. {
  23. case 1:
  24. printf("请输入你想插入的数据,以-1结束\n");
  25. do
  26. {
  27. scanf("%d", &x);
  28. if (x != -1)
  29. {
  30. SListPushBack(&plist, x);
  31. }
  32. } while (x != -1);
  33. break;
  34. case 2:
  35. printf("请输入你想插入的数据,以-1结束\n");
  36. do
  37. {
  38. scanf("%d", &x);
  39. if (x != -1)
  40. {
  41. SListPushFront(&plist, x);
  42. }
  43. } while (x != -1);
  44. break;
  45. case 3:
  46. SListPopBack(&plist);
  47. printf("删除成功!\n");
  48. break;
  49. case 4:
  50. SListPopFront(&plist);
  51. printf("删除成功!\n");
  52. break;
  53. case 5:
  54. printf("请先输入你要插入的位置的当前数据:\n");
  55. scanf("%d", &x);
  56. SLTNode* pos = SListFind(&plist, x);
  57. if (pos == NULL)
  58. {
  59. printf("该数据不存在,请重新选择随机插入选项进行操作!\n");
  60. }
  61. else
  62. {
  63. printf("该数据存在,请输入您要插入的数据:\n");
  64. scanf("%d", &x);
  65. SListInsert(&plist, pos, x);
  66. printf("插入成功!\n");
  67. }
  68. break;
  69. case 6:
  70. printf("请先输入你要删除的位置的当前数据:\n");
  71. scanf("%d", &x);
  72. SLTNode* pos1 = SListFind(&plist, x);
  73. if (pos1 == NULL)
  74. {
  75. printf("该数据不存在,请重新选择随机删除选项进行操作!\n");
  76. }
  77. else
  78. {
  79. SListErase(&plist, pos1);
  80. printf("删除成功!\n");
  81. }
  82. break;
  83. case 7:
  84. SListPrint(plist);
  85. break;
  86. case 0:
  87. printf("退出程序!\n");
  88. break;
  89. default:
  90. printf("输入的数字有误,请重新选择\n");
  91. break;
  92. }
  93. } while (input);
  94. }
  95. int main()
  96. {
  97. Text();
  98. return 0;
  99. }

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

闽ICP备14008679号