当前位置:   article > 正文

[C语言][数据结构][链表] 单链表的从零实现!

[C语言][数据结构][链表] 单链表的从零实现!

目录

零.必备知识

1.一级指针 && 二级指针

2. 节点的成员列表

    a.数据

    b.指向下一个节点的指针.

3. 动态内存空间的开辟 (malloc-calloc-realloc)

一.单链表的实现与销毁 

        1.1 节点的定义

        1.2 单链表的尾插

        1.3 单链表的头插

        1.4 单链表的尾删

        1.5 单链表的头删 

        1.6 单链表的查找

        1.7 在指定位置之前插入数据

        1.8 在指定位置之后插入数据

        1.9 删除指定位置的数据

        1.10 删除指定位置之后的数据

        1.11 销毁单链表 

二. 单链表源码

SingleList.h

SingleList.c 


零.必备知识

1.一级指针 && 二级指针

2. 节点的成员列表

    a.数据

    b.指向下一个节点的指针.

3. 动态内存空间的开辟 (malloc-calloc-realloc)


一.单链表的实现与销毁 

注:具体解释都在代码的注释中!(在代码中具体分析)

        1.1 节点的定义

        1.2 单链表的尾插

 

        1.3 单链表的头插

 

        1.4 单链表的尾删

        1.5 单链表的头删 

        1.6 单链表的查找

        1.7 在指定位置之前插入数据

        1.8 在指定位置之后插入数据

        

 

        1.9 删除指定位置的数据

        1.10 删除指定位置之后的数据

        1.11 销毁单链表 

二. 单链表源码

SingleList.h

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #pragma once
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <assert.h>
  6. // 节点的定义
  7. typedef int SLTDateType;
  8. typedef struct SingleListNode
  9. {
  10. SLTDateType date;
  11. struct SingleListNode* next;
  12. }SLTNode;
  13. // 单链表的展示
  14. void SLTPrint(SLTNode* phead);
  15. // 单链表的尾插
  16. void SLTPushBack(SLTNode** pphead, SLTDateType x);
  17. // 单链表的头插
  18. void SLTPushFront(SLTNode** pphead, SLTDateType x);
  19. // 单链表的尾删
  20. void SLTPopBack(SLTNode** pphead);
  21. // 单链表的头删
  22. void SLTPopFront(SLTNode** pphead);
  23. // 单链表的查找
  24. SLTNode* SLTFind(SLTNode* phead, SLTDateType x);
  25. // 在指定位置之前插入数据
  26. void SLTInsertBefore(SLTNode** pphead, SLTNode* pos, SLTDateType x);
  27. // 在指定位置之后插入数据
  28. void SLTInsertAfter(SLTNode** pphead, SLTNode* pos, SLTDateType x);
  29. // 删除指定位置的数据
  30. void SLTErase(SLTNode** pphead, SLTNode* pos);
  31. // 删除指定位置之后的数据
  32. void SLTEraseAfter(SLTNode** pphead, SLTNode* pos);
  33. // 销毁单链表
  34. void SLTDestroy(SLTNode** pphead);

SingleList.c 

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include "SingleList.h"
  3. // 单链表的展示
  4. void SLTPrint(SLTNode* phead)
  5. {
  6. SLTNode* pcur = phead; //current 当前的,现在的 currect 正确的
  7. while (pcur != NULL) {
  8. printf("%d->", pcur->date);
  9. pcur = pcur->next;
  10. }
  11. printf("NULL\n");
  12. }
  13. // 节点的创造
  14. SLTNode* SLTCreat(SLTDateType x)
  15. {
  16. SLTNode* newNode = (SLTNode*)malloc(sizeof(SLTNode));
  17. if (newNode == NULL) {
  18. printf("创建失败!\n");
  19. exit(1);
  20. }
  21. newNode->date = x;
  22. newNode->next = NULL;
  23. return newNode;
  24. }
  25. // 单链表的尾插
  26. void SLTPushBack(SLTNode** pphead, SLTDateType x)
  27. {
  28. assert(pphead);
  29. // 创建节点
  30. SLTNode* newNode = SLTCreat(x);
  31. // 没有节点
  32. if ((*pphead) == NULL) {
  33. (*pphead) = newNode;
  34. }
  35. else { // 有一个或多个节点
  36. SLTNode* pcur = (*pphead);
  37. while (pcur->next != NULL) {
  38. pcur = pcur->next;
  39. }
  40. pcur->next = newNode;
  41. }
  42. }
  43. // 单链表的头插
  44. void SLTPushFront(SLTNode** pphead, SLTDateType x)
  45. {
  46. assert(pphead);
  47. SLTNode* pcur = (*pphead);
  48. // 创建节点
  49. SLTNode* newNode = SLTCreat(x);
  50. // 没有节点
  51. if ((*pphead) == NULL) {
  52. (*pphead) = newNode;
  53. }
  54. else { // 有一个或者多个节点
  55. newNode->next = (*pphead);
  56. (*pphead) = newNode;
  57. }
  58. }
  59. // 单链表的尾删
  60. void SLTPopBack(SLTNode** pphead)
  61. {
  62. assert(pphead && (*pphead));
  63. SLTNode* pcur = (*pphead);
  64. SLTNode* prev = (*pphead);
  65. // 只有一个节点
  66. if (pcur->next == NULL) {
  67. free(*pphead);
  68. (*pphead) = NULL;
  69. pcur = NULL;
  70. prev = NULL;
  71. }
  72. else { // 有多个节点
  73. while (pcur->next != NULL) {
  74. prev = pcur;
  75. pcur = pcur->next;
  76. }
  77. free(pcur);
  78. pcur = NULL;
  79. prev->next = NULL;
  80. }
  81. }
  82. // 单链表的头删
  83. void SLTPopFront(SLTNode** pphead)
  84. {
  85. assert(pphead && (*pphead));
  86. SLTNode* pcur = (*pphead);
  87. // 只有一个节点
  88. if (pcur->next == NULL) {
  89. free(*pphead);
  90. (*pphead) = NULL;
  91. pcur = NULL;
  92. }
  93. else { //有多个节点
  94. (*pphead) = (*pphead)->next;
  95. free(pcur);
  96. pcur = NULL;
  97. }
  98. }
  99. // 单链表的查找
  100. SLTNode* SLTFind(SLTNode* phead, SLTDateType x)
  101. {
  102. SLTNode* pcur = phead;
  103. while (pcur != NULL) {
  104. if (pcur->date == x) {
  105. printf("找到了!\n");
  106. return pcur;
  107. }
  108. pcur = pcur->next;
  109. }
  110. printf("找不到!\n");
  111. return NULL;
  112. }
  113. // 在指定位置之前插入数据
  114. void SLTInsertBefore(SLTNode** pphead, SLTNode* pos, SLTDateType x)
  115. {
  116. assert(pphead);
  117. SLTNode* pcur = (*pphead);
  118. // 创建节点
  119. SLTNode* newNode = SLTCreat(x);
  120. // 头插
  121. if (pos == (*pphead) || (*pphead) == NULL) {
  122. SLTPushFront(pphead, x);
  123. }
  124. else { //正常插入
  125. while (pcur->next != NULL) {
  126. if (pcur->next == pos) {
  127. newNode->next = pcur->next;
  128. pcur->next = newNode;
  129. break;
  130. }
  131. pcur = pcur->next;
  132. }
  133. }
  134. }
  135. // 在指定位置之后插入数据
  136. void SLTInsertAfter(SLTNode** pphead, SLTNode* pos, SLTDateType x)
  137. {
  138. assert(pphead);
  139. // 创建节点
  140. SLTNode* newNode = SLTCreat(x);
  141. if ((*pphead) == NULL || pos == (*pphead)) {
  142. // 尾插
  143. SLTPushBack(pphead, x);
  144. }
  145. else { //正常插入
  146. SLTNode* pcur = (*pphead);
  147. while (pcur->next != NULL) {
  148. if (pcur == pos) {
  149. newNode->next = pcur->next;
  150. pcur->next = newNode;
  151. break;
  152. }
  153. pcur = pcur->next;
  154. }
  155. }
  156. }
  157. // 删除指定位置的数据
  158. void SLTErase(SLTNode** pphead, SLTNode* pos)
  159. {
  160. assert(pphead && (*pphead));
  161. // 处理特殊情况(头删)
  162. if ((*pphead) == pos) {
  163. SLTPopFront(pphead);
  164. }
  165. else {
  166. SLTNode* prev = (*pphead);
  167. SLTNode* pcur = (*pphead);
  168. while (pcur != NULL) {
  169. if (pcur == pos) {
  170. prev->next = pcur->next;
  171. free(pcur);
  172. pcur = NULL;
  173. prev = NULL;
  174. break;
  175. }
  176. prev = pcur;
  177. pcur = pcur->next;
  178. }
  179. }
  180. }
  181. // 删除指定位置之后的数据
  182. void SLTEraseAfter(SLTNode** pphead, SLTNode* pos)
  183. {
  184. assert(pphead && (*pphead));
  185. SLTNode* pcur = (*pphead);
  186. while (pcur->next != NULL) {
  187. if (pcur == pos) {
  188. SLTNode* tmp = pcur->next;
  189. pcur->next = pcur->next->next;
  190. free(tmp);
  191. tmp = NULL;
  192. break;
  193. }
  194. pcur = pcur->next;
  195. }
  196. }
  197. // 销毁单链表
  198. void SLTDestroy(SLTNode** pphead)
  199. {
  200. assert(pphead && (*pphead));
  201. SLTNode* pcur = (*pphead);
  202. SLTNode* prev = (*pphead);
  203. while (pcur != NULL) {
  204. prev = pcur;
  205. pcur = pcur->next;
  206. free(prev);
  207. }
  208. prev = NULL;
  209. (*pphead) = NULL;
  210. }

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

闽ICP备14008679号