单链表

  1. #include "stdio.h"
  2. #include "string.h"
  3. #include "ctype.h"
  4. #include "stdlib.h"
  5. #include "math.h"
  6. #include "time.h"
  7. #define OK 1
  8. #define ERROR 0
  9. #define TRUE 1
  10. #define FALSE 0
  11. #define MAXSIZE 20 /* 存储空间初始分配量 */
  12. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  13. typedef int ElemType; /* ElemType类型根据实际情况而定,这里假设为int */
  14. typedef struct Node { /* 线性表的单链表存储结构 */
  15. ElemType data;
  16. struct Node *next;
  17. } Node;
  18. typedef struct Node *LinkList; /* 定义LinkList */
  19. /*打印某个数*/
  20. Status visit(ElemType c) {
  21. printf("%d ", c);
  22. return OK;
  23. }
  24. /* 初始化顺序线性表 */
  25. //申请的结果有两种
  26. //1、失败:return ERROR
  27. //2、成功:设定指针域为空、return OK
  28. Status InitList(LinkList *L) {
  29. *L = (LinkList)malloc(sizeof(Node)); /* 产生头结点,并使L指向此头结点 */
  30. if (!(*L)) /* 存储分配失败 */
  31. return ERROR;
  32. (*L)->next = NULL; /* 指针域为空 */
  33. return OK;
  34. }
  35. /* 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
  36. Status ListEmpty(LinkList L) {
  37. if (L->next)
  38. return FALSE;
  39. else
  40. return TRUE;
  41. }
  42. /* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */
  43. Status ClearList(LinkList *L) {
  44. LinkList p, q;
  45. p = (*L)->next; /* p指向第一个结点 */
  46. while (p) /* 没到表尾 */
  47. {
  48. q = p->next; /* 用q保存p的下一节点*/
  49. free(p); /* 释放p节点的空间*/
  50. p = q;
  51. }
  52. (*L)->next = NULL; /* 最后,头结点指针域为空 */
  53. return OK;
  54. }
  55. /* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
  56. int ListLength(LinkList L) {
  57. int i = 0; /* 计数器 */
  58. LinkList p = L->next; /* important:p指向第一个结点 */
  59. while (p) {
  60. i++;
  61. p = p->next;
  62. }
  63. return i;
  64. }
  65. /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
  66. /* 操作结果:用e返回L中第i个数据元素的值 */
  67. Status GetElem(LinkList L, int i, ElemType *e) {
  68. int j;
  69. LinkList p; /* 声明一结点p */
  70. p = L->next; /* 让p指向链表L的第一个结点 */
  71. j = 1; /* j为计数器 */
  72. while (p && j < i) /* p不为空或者计数器j还没有等于i时,循环继续 */
  73. {
  74. p = p->next; /* 让p指向下一个结点 */
  75. ++j;
  76. }
  77. if (!p || j > i)
  78. return ERROR; /* 第i个元素不存在 */
  79. *e = p->data; /* 取第i个元素的数据 */
  80. return OK;
  81. }
  82. /* 初始条件:顺序线性表L已存在 */
  83. /* 操作结果:返回L中第1个与e满足关系的数据元素的位序。 */
  84. /* 若这样的数据元素不存在,则返回值为0 */
  85. int LocateElem(LinkList L, ElemType e) {
  86. int i = 0;
  87. LinkList p = L->next;
  88. while (p) {
  89. i++;
  90. if (p->data == e) /* 找到这样的数据元素 */
  91. return i;
  92. p = p->next;
  93. }
  94. return 0;
  95. }
  96. /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
  97. /* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
  98. Status ListInsert(LinkList *L, int i, ElemType e) {
  99. int j;
  100. LinkList p, s;
  101. p = *L;
  102. j = 1;
  103. while (p && j < i) /* 寻找第i个结点 */
  104. {
  105. p = p->next;
  106. ++j;
  107. }
  108. if (!p || j > i)
  109. return ERROR; /* 第i个元素不存在 */
  110. s = (LinkList)malloc(sizeof(Node)); /* 生成新结点(C语言标准函数) */
  111. s->data = e;
  112. s->next = p->next; /* 将p的后继结点赋值给s的后继 */
  113. p->next = s; /* 将s赋值给p的后继 */
  114. return OK;
  115. }
  116. /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
  117. /* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
  118. Status ListDelete(LinkList *L, int i, ElemType *e) {
  119. int j;
  120. LinkList p, q;
  121. p = *L;
  122. j = 1;
  123. while (p->next && j < i) /* 遍历寻找第i个元素 */
  124. {
  125. p = p->next;
  126. ++j;
  127. }
  128. if (!(p->next) || j > i)
  129. return ERROR; /* 第i个元素不存在 */
  130. //插入和删除的前面这部分相同。
  131. q = p->next;
  132. p->next = q->next; /* 将q的后继赋值给p的后继 */
  133. *e = q->data; /* 将q结点中的数据给e */
  134. free(q); /* 让系统回收此结点,释放内存 */
  135. return OK;
  136. }
  137. /* 初始条件:顺序线性表L已存在 */
  138. /* 操作结果:依次对L的每个数据元素输出 */
  139. Status ListTraverse(LinkList L) {
  140. LinkList p = L->next;
  141. while (p) {
  142. visit(p->data);
  143. p = p->next;
  144. }
  145. printf(" ");
  146. return OK;
  147. }
  148. /* 随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) */
  149. void CreateListHead(LinkList *L, int n) {
  150. LinkList p;
  151. int i;
  152. srand(time(0)); /* 初始化随机数种子 */
  153. *L = (LinkList)malloc(sizeof(Node));
  154. (*L)->next = NULL; /* 先建立一个带头结点的单链表 */
  155. for (i = 0; i < n; i++) {
  156. p = (LinkList)malloc(sizeof(Node)); /* 生成新结点 */
  157. p->data = rand() % 100 + 1; /* 随机生成100以内的数字 */
  158. p->next = (*L)->next;
  159. (*L)->next = p; /* 插入到表头 */
  160. }
  161. }
  162. /* 随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法) */
  163. void CreateListTail(LinkList *L, int n) {
  164. LinkList p, r;
  165. int i;
  166. srand(time(0)); /* 初始化随机数种子 */
  167. *L = (LinkList)malloc(sizeof(Node)); /* L为整个线性表 */
  168. r = *L; /* r为指向尾部的结点 */
  169. for (i = 0; i < n; i++) {
  170. p = (Node *)malloc(sizeof(Node)); /* 生成新结点 */
  171. p->data = rand() % 100 + 1; /* 随机生成100以内的数字 */
  172. r->next = p; /* 将表尾终端结点的指针指向新结点 */
  173. r = p; /* 将当前的新结点定义为表尾终端结点 */
  174. }
  175. r->next = NULL; /* 表示当前链表结束 */
  176. }
  177. int main() {
  178. LinkList L;
  179. ElemType e;
  180. Status i;
  181. int j, k;
  182. i = InitList(&L);
  183. printf("初始化L后:ListLength(L)=%d ", ListLength(L));
  184. for (j = 1; j <= 5; j++)
  185. i = ListInsert(&L, 1, j);
  186. printf("在L的表头依次插入1~5后:L.data=");
  187. ListTraverse(L);
  188. printf("ListLength(L)=%d ", ListLength(L));
  189. i = ListEmpty(L);
  190. printf("L是否空:i=%d(1:是 0:否) ", i);
  191. i = ClearList(&L);
  192. printf("清空L后:ListLength(L)=%d ", ListLength(L));
  193. i = ListEmpty(L);
  194. printf("L是否空:i=%d(1:是 0:否) ", i);
  195. for (j = 1; j <= 10; j++)
  196. ListInsert(&L, j, j);
  197. printf("在L的表尾依次插入1~10后:L.data=");
  198. ListTraverse(L);
  199. printf("ListLength(L)=%d ", ListLength(L));
  200. ListInsert(&L, 1, 0);
  201. printf("在L的表头插入0后:L.data=");
  202. ListTraverse(L);
  203. printf("ListLength(L)=%d ", ListLength(L));
  204. GetElem(L, 5, &e);
  205. printf("第5个元素的值为:%d ", e);
  206. for (j = 3; j <= 4; j++) {
  207. k = LocateElem(L, j);
  208. if (k)
  209. printf("第%d个元素的值为%d ", k, j);
  210. else
  211. printf("没有值为%d的元素 ", j);
  212. }
  213. k = ListLength(L); /* k为表长 */
  214. for (j = k + 1; j >= k; j--) {
  215. i = ListDelete(&L, j, &e); /* 删除第j个数据 */
  216. if (i == ERROR)
  217. printf("删除第%d个数据失败 ", j);
  218. else
  219. printf("删除第%d个的元素值为:%d ", j, e);
  220. }
  221. printf("依次输出L的元素:");
  222. ListTraverse(L);
  223. j = 5;
  224. ListDelete(&L, j, &e); /* 删除第5个数据 */
  225. printf("删除第%d个的元素值为:%d ", j, e);
  226. printf("依次输出L的元素:");
  227. ListTraverse(L);
  228. i = ClearList(&L);
  229. printf(" 清空L后:ListLength(L)=%d ", ListLength(L));
  230. CreateListHead(&L, 20);
  231. printf("整体创建L的元素(头插法):");
  232. ListTraverse(L);
  233. i = ClearList(&L);
  234. printf(" 删除L后:ListLength(L)=%d ", ListLength(L));
  235. CreateListTail(&L, 20);
  236. printf("整体创建L的元素(尾插法):");
  237. ListTraverse(L);
  238. return 0;
  239. }





原文地址:https://www.cnblogs.com/zhuzhenfeng/p/4626513.html