1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #define MAXSIZE 20
5 #define ok 1
6 #define error 0
7 #define true 1
8 #define false 0
9
10 // 单链表的主要核心思想是"工作指针后移"
11 // 需要注意的是,传入的指针的值尽量不要做修改
12 // 以免发生错误
13
14 typedef int Status;
15 typedef int ElemType;
16
17 typedef struct Node
18 {
19 ElemType data;
20 struct Node *next;
21 }Node;
22 typedef struct Node *LinkList;
23
24 Status Getelem(LinkList L, int i, ElemType *e)
25 {
26 int j;
27 LinkList p;
28
29 p = L->next;
30 j = 1;
31
32 while (p && j < i)
33 {
34 p = p->next;
35 j++;
36 }
37
38 if (!p || j > i)
39 {
40 return error;
41 }
42 *e = p->data;
43 return ok;
44 }
45
46 Status ListInsert(LinkList *L, int i, ElemType e)
47 {
48 int j;
49 LinkList p, s;
50
51 p = *L;
52 j = 1;
53
54 while (p && j < i)
55 {
56 p = p->next;
57 j++;
58 }
59 if (!p || j > i)
60 return error;
61 s = (LinkList)malloc(sizeof(Node));
62 s->data = e;
63 s->next = p->next;
64 p->next = s;
65 return ok;
66 }
67
68 Status ListDelete(LinkList *L, int i, ElemType *e)
69 {
70 int j;
71 LinkList p, q;
72
73 p = L;
74 j = 1;
75 while (p->next && j < i)
76 {
77 p = p->next;
78 j++;
79 }
80 if (!(p->next) || j > i)
81 return error;
82
83 q = p->next;
84 p->next = q->next;
85 *e = q->data;
86 free(q);
87 return ok;
88 }
89
90 // 头插法
91 void CreateListHead(LinkList *L, int n)
92 {
93 LinkList p;
94 int i;
95
96 srand(time(0));
97 *L = (LinkList)malloc(sizeof(Node));
98 (*L)->next = NULL;
99
100 for (i = 0; i < n; i++)
101 {
102 p = (LinkList)malloc(sizeof(Node));
103 p->data = rand() % 100 + 1;
104 p->next = (*L)->next;
105 (*L)->next = p;
106 }
107 }
108
109 // 尾插法
110 // 注意L与r的关系,L是指整个单链表,而r是指向尾结点的变量,也就是指向尾结点的工作指针
111 void CreateListTail(LinkList *L, int n)
112 {
113 LinkList p, r;
114 int i;
115 srand(time(0));
116
117 *L = (LinkList)malloc(sizeof(Node));
118 r = *L; /*r为指向尾部的结点*/
119
120 for (i = 0; i < n; i++)
121 {
122 p = (Node *)malloc(sizeof(Node));
123 p->data = rand() % 100 + 1;
124 r->next = p;
125 r = p;
126 }
127 r->next = NULL; //表示当前链表结束
128 }
129
130 //单链表的整表删除
131 /*
132 算法思路如下:
133 1、声明一结点p和q
134 2、将第一个结点赋值给p
135 3、循环:
136 将下一结点赋值给q;
137 释放p
138 将q赋值给p
139 实现代码算法如下:
140 */
141 Status ClearList(LinkList *L)
142 {
143 LinkList p, q;
144 p = (*L)->next; // p指向第一个结点
145 while (p)
146 {
147 q = p->next;
148 free(p);
149 p = q;
150 }
151 (*L)->next = NULL; //头结点指针域为空
152 return ok;
153 }
154
155 /*
156 单链表结构与顺序存储结构的优缺点:
157 顺序存储查找方便,插入删除较为麻烦,且预分配空间容易造成空间浪费
158 单链表查找时间复杂度较高i,但插入和删除极为灵活,且空间是按需分配,不会造成浪费
159 据此可以得出:
160 若线性表需要频繁查找,很少进行插入删除操作时,宜采用顺序存储结构
161 若需要频繁插入和删除时,宜采用单链表结构。
162 */
163
164 int main()
165 {
166 return 0;
167 }