1 来自https://www.bilibili.com/video/av2975983/?p=17&t=13
2 个人感悟:循环链表的插入与删除与普通链表的区别就是在一个结点 而且初始化功能循环链表的头指向尾则代表空 普通链表头指针指针域指向NULL为空
3
4 //算法描述
5 //链表存储结构定义
6 typedef struct CLinkList
7 {
8 int data;
9 struct ClinkList *next;
10 }node;
11 #define LEN sizeof(node)
12 //初始化循环链表
13 void ds_init(node **pNode)
14 {
15 int item;
16 node *temp;
17 node *target;
18
19 printf("输入结点的值,输入0完成初始化");
20
21 while(1)
22 {
23 scanf("%d",&item);
24
25 if(item == 0)
26 return;
27
28 if((*pNode) == NULL)
29 {//循环链表只有一个结点
30 *pNode = (node *)malloc(LEN);
31 if(!(*pNode))
32 exit(1);
33 (*pNode)->data = item;
34 (*pNode)->next = *pNode;
35 }
36 else
37 { //target最终指向最后一个结点
38 for(target = (*pNode);target->next != (*pNode);target = target->next)
39
40 temp = (node *)malloc(LEN);
41 if(!temp)
42 exit(1);
43
44 temp->data = item;
45 temp->next = *pNode;
46 target->next = temp;
47 }
48 }
49 }
50
51 //插入结点
52 void ds_insert(node **pNode,int i)//参数:链表的第一个结点,插入的位置
53 {
54 node *temp;
55 node *target;
56 node *p;
57 int item;
58 int j = 1;
59
60 printf("输入要插入结点的值:");
61 scanf("%d",&item);
62
63 if(i == 1)
64 { //新插入的结点作为第一个结点
65 temp = (node *)malloc(LEN);
66
67 if(!temp)
68 exit(1);
69
70 temp->data = item;
71 //寻找最后一个结点
72 for(target = (*pNode); target->next != (*pNode); target = target->next);
73
74 temp->next = (*pNode);
75 target->next = temp;
76 *pNode = temp;
77 }
78 else
79 {
80 target = *pNode; //target指向第一个元素
81
82 for(j; j < (i-1); j++)//找到要插入的位置
83 {
84 target = target->next;
85 }
86 target = (node *)malloc(LEN);
87
88 if(!temp)
89 exit(0);
90
91 temp->data = item;
92 p = target->next; //p作为中间变量
93 target->next = temp; //target指向新插入的结点
94 temp->next = p; //新插入的结点指向 p中存的是旧版本的第i个位置的结点
95 }
96 }
97 //删除结点
98 void ds_delete(node **pNode,int i)
99 {
100 node *target;
101 node temp;
102 int j = 1;
103
104 if(i == 1)
105 {
106 //删除的是第一个结点
107 //找到最后一个结点
108 for(target = *pNode; target->next != *pNode; target = target->next);
109
110 temp = *pNode; //保存第一个结点以删除
111 *pNode = (*pNode)->next;//第一个结点指向下一个结点
112 target->next = *pNode;//尾结点指向第一个结点
113 free(temp);//释放
114 }
115 else
116 {
117 target = *pNode;
118
119 for(; j < i-1; j++)
120 {
121 target = target->next;//target只是指向要删除的结点
122 }
123
124 temp = target->next;
125 target->next = temp->next;
126 free(temp);
127 }
128 }
129 //返回结点所在位置
130 int ds_search(node *pNode,int i)
131 {
132 node *target;
133 int i = 1;
134
135 for(target = pNode; target->data != elem && target->next != pNode; i++)
136 {
137 target = target->nexxt;
138 }
139
140 if(target->next == pNode) //说明表中不存在该元素
141 return 0;
142 else
143 return i;
144 }
145
146
147 相关代码实现:
148 #include <stdio.h>
149 #include <stdlib.h>
150
151 /*链表存储结构的定义*/
152 typedef struct CLinkList
153 {
154 int data;
155 struct CLinkList *next;
156 }node;
157
158 /************************************************************************/
159 /* 操作 */
160 /************************************************************************/
161
162 /*初始化循环链表*/
163 void ds_init(node **pNode)
164 {
165 int item;
166 node *temp;
167 node *target;
168
169 printf("输入结点的值,输入0完成初始化\n");
170
171 while(1)
172 {
173 scanf("%d", &item);
174 fflush(stdin);
175
176 if(item == 0)
177 return;
178
179 if((*pNode) == NULL)
180 { /*循环链表中只有一个结点*/
181 *pNode = (node*)malloc(sizeof(struct CLinkList));
182 if(!(*pNode))
183 exit(0);
184 (*pNode)->data = item;
185 (*pNode)->next = *pNode;
186 }
187 else
188 {
189 /*找到next指向第一个结点的结点*/
190 for(target = (*pNode); target->next != (*pNode); target = target->next)
191 ;
192
193 /*生成一个新的结点*/
194 temp = (node *)malloc(sizeof(struct CLinkList));
195
196 if(!temp)
197 exit(0);
198
199 temp->data = item;
200 temp->next = *pNode;
201 target->next = temp;
202 }
203 }
204 }
205
206 /*插入结点*/
207 /*参数:链表的第一个结点,插入的位置*/
208 void ds_insert(node **pNode , int i)
209 {
210 node *temp;
211 node *target;
212 node *p;
213 int item;
214 int j = 1;
215
216 printf("输入要插入结点的值:");
217 scanf("%d", &item);
218
219 if(i == 1)
220 { //新插入的结点作为第一个结点
221 temp = (node *)malloc(sizeof(struct CLinkList));
222
223 if(!temp)
224 exit(0);
225
226 temp ->data = item;
227
228 /*寻找到最后一个结点*/
229 for(target = (*pNode); target->next != (*pNode); target = target->next)
230 ;
231
232 temp->next = (*pNode);
233 target->next = temp;
234 *pNode = temp;
235 }
236 else
237 {
238 target = *pNode;
239
240 for( ; j < (i-1); ++j )
241 {
242 target=target->next;
243 }
244
245 temp = (node *)malloc(sizeof(struct CLinkList));
246
247 if(!temp)
248 exit(0);
249
250 temp ->data = item;
251 p = target->next;
252 target->next = temp;
253 temp->next = p;
254 }
255 }
256
257 /*删除结点*/
258 void ds_delete(node **pNode, int i)
259 {
260 node *target;
261 node *temp;
262 int j = 1;
263
264 if(i == 1)
265 { //删除的是第一个结点
266 /*找到最后一个结点*/
267 for(target = *pNode; target->next != *pNode;target = target->next)
268 ;
269
270 temp = *pNode;
271 *pNode = (*pNode)->next;
272 target->next = *pNode;
273 free(temp);
274 }
275 else
276 {
277 target = *pNode;
278
279 for( ; j < i-1; ++j )
280 {
281 target = target->next;
282 }
283
284 temp = target->next;
285 target->next = temp->next;
286 free(temp);
287 }
288 }
289
290 /*返回结点所在位置*/
291 int ds_search(node *pNode, int elem)
292 {
293 node *target;
294 int i = 1;
295
296 for(target = pNode; target->data != elem && target->next != pNode; ++i)
297 {
298 target = target->next;
299 }
300
301 if(target->next == pNode) /*表中不存在该元素*/
302 return 0;
303 else
304 return i;
305 }
306
307 /*遍历*/
308 void ds_traverse(node *pNode)
309 {
310 node *temp;
311 temp = pNode;
312 printf("***********链表中的元素******************\n");
313
314 do
315 {
316 printf("%4d ", temp->data);
317 }while((temp = temp->next) != pNode);
318
319 printf("\n");
320 }
321
322 int main()
323 {
324 node *pHead = NULL;
325 char opp;
326 int find;
327
328 printf("1.初始化链表 \n\n2.插入结点 \n\n3.删除结点 \n\n4.返回结点位置 \n\n5.遍历链表 \n\n0.退出 \n\n请选择你的操作:");
329 while(opp != '0')
330 {
331 scanf("%c", &opp);
332 switch(opp)
333 {
334 case '1':
335 ds_init(&pHead);
336 printf("\n");
337 ds_traverse(pHead);
338 break;
339
340 case '2':
341 printf("输入需要插入结点的位置?");
342 scanf("%d", &find);
343 ds_insert(&pHead, find);
344 printf("在位置%d插入值后:\n", find);
345 ds_traverse(pHead);
346 printf("\n");
347 break;
348
349 case '3':
350 printf("输入需要删除的结点位置?");
351 scanf("%d", &find);
352 ds_delete(&pHead, find);
353 printf("删除第%d个结点后:\n", find);
354 ds_traverse(pHead);
355 printf("\n");
356 break;
357
358 case '4':
359 printf("你要查找倒数第几个结点的值?");
360 scanf("%d", &find);
361 printf("元素%d所在位置:%d\n", find, ds_search(pHead, find));
362 //ListTraverse(L);
363 printf("\n");
364 break;
365
366 case '5':
367 ds_traverse(pHead);
368 printf("\n");
369 break;
370
371 case '0':
372 exit(0);
373 }
374 }
375
376 return 0;
377 }
378
379 //自己实践的代码
380 一个简单的创建以及输出
381 #include<stdio.h>
382 #include<stdlib.h>
383
384 typedef struct Node
385 {
386 int data;
387 struct Node *next;
388 }LinkList;
389
390 #define LEN sizeof(LinkList)
391
392 LinkList *initList() //设置头结点
393 {
394 int dat;
395 LinkList *temp;
396 LinkList *target;
397 LinkList *pNode = NULL;
398
399 printf("输入以0结束\n");
400
401 while(1)
402 {
403 scanf("%d",&dat);
404 if(dat == 0)
405 break;
406
407 if(pNode == NULL)
408 {
409 pNode = (LinkList *)malloc(LEN);
410 if(pNode == NULL)
411 exit(1);
412 pNode->data = dat;
413 pNode->next = pNode;
414 }
415 else
416 {
417 for(target=pNode; target->next!=pNode; target=target->next);
418
419 temp = (LinkList *)malloc(LEN);
420 if(temp == NULL)
421 exit(1);
422
423 temp->data = dat;
424 temp->next = pNode; //新插入数据的指针域指向头
425 target->next = temp; //指向末尾结点的target指向新插入的结点
426 }
427
428 }
429
430 return pNode;
431
432 }
433
434 void printList(LinkList *pNode)
435 {
436 LinkList *temp;
437 temp = pNode;
438 printf("链表中的元素是:\n");
439
440 do
441 {
442 printf("%4d",temp->data);
443 temp = temp->next;
444 }while(temp != pNode);
445 printf("\n");
446 }
447
448 int main(void)
449 {
450 LinkList *pNode;
451 LinkList *L;
452 pNode = initList();
453 printList(pNode);
454
455 return 0;
456 }