1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<time.h>
4
5 #define OK 1
6 #define ERROR 0
7 #define TRUE 1
8 #define FALSE 0
9
10 #define MAXSIZE 20 /* 存储空间初始分配量 */
11
12 typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
13 typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */
14
15 typedef struct Node
16 {
17 ElemType data;
18 struct Node *next;
19 }Node;
20 /* 定义LinkList */
21 typedef struct Node *LinkList;
22
23 /* 初始化顺序线性表 */
24 Status InitList(LinkList *L)
25 {
26 *L=(LinkList)malloc(sizeof(Node)); /* 产生头结点,并使L指向此头结点 */
27 if(!(*L)) /* 存储分配失败 */
28 {
29 return ERROR;
30 }
31 (*L)->next=NULL; /* 指针域为空 */
32
33 return OK;
34 }
35
36 /* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
37 int ListLength(LinkList L)
38 {
39 int i=0;
40 LinkList p=L->next; /* p指向第一个结点 */
41 while(p)
42 {
43 i++;
44 p=p->next;
45 }
46 return i;
47 }
48
49 /* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */
50 Status ClearList(LinkList *L)
51 {
52 LinkList p,q;
53 p=(*L)->next; /* p指向第一个结点 */
54 while(p) /* 没到表尾 */
55 {
56 q=p->next;
57 free(p);
58 p=q;
59 }
60 (*L)->next=NULL; /* 头结点指针域为空 */
61 return OK;
62 }
63
64 /* 初始条件:顺序线性表L已存在 */
65 /* 操作结果:依次对L的每个数据元素输出 */
66 Status ListTraverse(LinkList L)
67 {
68 LinkList p=L->next;
69 while(p)
70 {
71 visit(p->data);
72 p=p->next;
73 }
74 printf("\n");
75 return OK;
76 }
77
78 Status visit(ElemType c)
79 {
80 printf("-> %d ",c);
81 return OK;
82 }
83
84 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
85 /* 操作结果:用e返回L中第i个数据元素的值 */
86 Status GetElem(LinkList L,int i,ElemType *e)
87 {
88 int j;
89 LinkList p; /* 声明一结点p */
90 p = L->next; /* 让p指向链表L的第一个结点 */
91 j = 1; /* j为计数器 */
92 while (p && j < i) /* p不为空或者计数器j还没有等于i时,循环继续 */
93 {
94 p = p->next; /* 让p指向下一个结点 */
95 ++j;
96 }
97 if ( !p || j>i )
98 return ERROR; /* 第i个元素不存在 */
99 *e = p->data; /* 取第i个元素的数据 */
100 return OK;
101 }
102
103 /* 初始条件:顺序线性表L已存在 */
104 /* 操作结果:返回L中第1个与e满足关系的数据元素的位序。 */
105 /* 若这样的数据元素不存在,则返回值为0 */
106 int LocateElem(LinkList L,ElemType e)
107 {
108 int i=0;
109 LinkList p=L->next;
110 while(p)
111 {
112 i++;
113 if(p->data==e) /* 找到这样的数据元素 */
114 return i;
115 p=p->next;
116 }
117
118 return 0;
119 }
120
121 /* 随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) */
122 void CreateListHead(LinkList *L, int n)
123 {
124 LinkList p;
125 int i;
126 srand(time(0)); /* 初始化随机数种子 */
127 *L = (LinkList)malloc(sizeof(Node));
128 (*L)->next = NULL; /* 先建立一个带头结点的单链表 */
129 for (i=0; i < n; i++)
130 {
131 p = (LinkList)malloc(sizeof(Node)); /* 生成新结点 */
132 p->data = rand()%100+1; /* 随机生成100以内的数字 */
133 p->next = (*L)->next;
134 (*L)->next = p; /* 插入到表头 */
135 }
136 }
137
138 /* 随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法) */
139 void CreateListTail(LinkList *L, int n)
140 {
141 LinkList p,r;
142 int i;
143 srand(time(0)); /* 初始化随机数种子 */
144 *L = (LinkList)malloc(sizeof(Node)); /* L为整个线性表 */
145 r=*L; /* r为指向尾部的结点 */
146 for (i=0; i < n; i++)
147 {
148 p = (Node *)malloc(sizeof(Node)); /* 生成新结点 */
149 p->data = rand()%100+1; /* 随机生成100以内的数字 */
150 r->next=p; /* 将表尾终端结点的指针指向新结点 */
151 r = p; /* 将当前的新结点定义为表尾终端结点 */
152 }
153 r->next = NULL; /* 表示当前链表结束 */
154 }
155
156 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
157 /* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
158 Status ListInsert(LinkList *L,int i,ElemType e)
159 {
160 int j;
161 LinkList p,s;
162 p = *L; /* 声明一个结点 p,指向头结点 */
163 j = 1;
164 while (p && j < i) /* 寻找第i个结点 */
165 {
166 p = p->next;
167 ++j;
168 }
169 if (!p || j > i)
170 return ERROR; /* 第i个元素不存在 */
171 s = (LinkList)malloc(sizeof(Node)); /* 生成新结点(C语言标准函数) */
172 s->data = e;
173 s->next = p->next; /* 将p的后继结点赋值给s的后继 */
174 p->next = s; /* 将s赋值给p的后继 */
175 return OK;
176 }
177
178 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
179 /* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
180 Status ListDelete(LinkList *L,int i,ElemType *e)
181 {
182 int j;
183 LinkList p,q;
184 p = *L;
185 j = 1;
186 while (p->next && j < i) /* 遍历寻找第i个元素 */
187 {
188 p = p->next;
189 ++j;
190 }
191 if (!(p->next) || j > i)
192 return ERROR; /* 第i个元素不存在 */
193 q = p->next;
194 p->next = q->next; /* 将q的后继赋值给p的后继 */
195 *e = q->data; /* 将q结点中的数据给e */
196 free(q); /* 让系统回收此结点,释放内存 */
197 return OK;
198 }
199
200 /* 单链表反转/逆序 */
201 Status ListReverse(LinkList L)
202 {
203 LinkList current,pnext,prev;
204 if(L == NULL || L->next == NULL)
205 return L;
206 current = L->next; /* p1指向链表头节点的下一个节点 */
207 pnext = current->next;
208 current->next = NULL;
209 while(pnext)
210 {
211 prev = pnext->next;
212 pnext->next = current;
213 current = pnext;
214 pnext = prev;
215 }
216 //printf("current = %d,next = %d \n",current->data,current->next->data);
217 L->next = current; /* 将链表头节点指向p1 */
218 return L;
219 }
220
221 Status ListReverse2(LinkList L)
222 {
223 LinkList current, p;
224
225 if (L == NULL)
226 {
227 return NULL;
228 }
229 current = L->next;
230 while (current->next != NULL)
231 {
232 p = current->next;
233 current->next = p->next;
234 p->next = L->next;
235 L->next = p;
236 ListTraverse(L);
237 printf("current = %d, \n", current -> data);
238 }
239 return L;
240 }
241
242 int main()
243 {
244 LinkList L;
245 Status i;
246 int j,k,pos,value;
247 char opp;
248 ElemType e;
249
250 i=InitList(&L);
251 printf("链表L初始化完毕,ListLength(L)=%d\n",ListLength(L));
252
253 printf("\n1.整表创建(头插法) \n2.整表创建(尾插法) \n3.遍历操作 \n4.插入操作");
254 printf("\n5.删除操作 \n6.获取结点数据 \n7.查找某个数是否在链表中 \n8.置空链表");
255 printf("\n9.链表反转逆序");
256 printf("\n0.退出 \n请选择你的操作:\n");
257 while(opp != '0'){
258 scanf("%c",&opp);
259 switch(opp){
260 case '1':
261 CreateListHead(&L,10);
262 printf("整体创建L的元素(头插法):\n");
263 ListTraverse(L);
264 printf("\n");
265 break;
266
267 case '2':
268 CreateListTail(&L,10);
269 printf("整体创建L的元素(尾插法):\n");
270 ListTraverse(L);
271 printf("\n");
272 break;
273
274 case '3':
275 ListTraverse(L);
276 printf("\n");
277 break;
278
279 case '4':
280 printf("要在第几个位置插入元素?");
281 scanf("%d",&pos);
282 printf("插入的元素值是多少?");
283 scanf("%d",&value);
284 ListInsert(&L,pos,value);
285 ListTraverse(L);
286 printf("\n");
287 break;
288
289 case '5':
290 printf("要删除第几个元素?");
291 scanf("%d",&pos);
292 ListDelete(&L,pos,&e);
293 printf("删除第%d个元素成功,现在链表为:\n", pos);
294 ListTraverse(L);
295 printf("\n");
296 break;
297
298 case '6':
299 printf("你需要获取第几个元素?");
300 scanf("%d",&pos);
301 GetElem(L,pos,&e);
302 printf("第%d个元素的值为:%d\n", pos, e);
303 printf("\n");
304 break;
305
306 case '7':
307 printf("输入你需要查找的数:");
308 scanf("%d",&pos);
309 k=LocateElem(L,pos);
310 if(k)
311 printf("第%d个元素的值为%d\n",k,pos);
312 else
313 printf("没有值为%d的元素\n",pos);
314 printf("\n");
315 break;
316
317 case '8':
318 i=ClearList(&L);
319 printf("\n清空L后:ListLength(L)=%d\n",ListLength(L));
320 ListTraverse(L);
321 printf("\n");
322 break;
323
324 case '9':
325 ListReverse2(L);
326 printf("\n反转L后\n");
327 ListTraverse(L);
328 printf("\n");
329 break;
330
331 case '0':
332 exit(0);
333 }
334 }
335 return 0;
336 }