线性表:循环链表

Posted zhenglijie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表:循环链表相关的知识,希望对你有一定的参考价值。

  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完成初始化
");
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("***********链表中的元素******************
");
313 
314     do
315     {
316         printf("%4d ", temp->data);
317     }while((temp = temp->next) != pNode);
318 
319     printf("
");
320 }
321 
322 int main()
323 {
324     node *pHead = NULL;
325     char opp;
326     int find;
327 
328     printf("1.初始化链表 

2.插入结点 

3.删除结点 

4.返回结点位置 

5.遍历链表  

0.退出 

请选择你的操作:");
329     while(opp != 0)
330     {
331         scanf("%c", &opp);
332         switch(opp)
333         {
334             case 1:
335                 ds_init(&pHead);
336                 printf("
");
337                 ds_traverse(pHead);
338                 break;
339 
340             case 2:
341                 printf("输入需要插入结点的位置?");
342                 scanf("%d",  &find);
343                 ds_insert(&pHead, find);
344                 printf("在位置%d插入值后:
",  find);
345                 ds_traverse(pHead);
346                 printf("
");
347                 break;
348 
349             case 3:
350                 printf("输入需要删除的结点位置?");
351                 scanf("%d",  &find);
352                 ds_delete(&pHead, find);
353                 printf("删除第%d个结点后:
",  find);
354                 ds_traverse(pHead);
355                 printf("
");
356                 break;
357 
358             case 4:
359                 printf("你要查找倒数第几个结点的值?");
360                 scanf("%d",  &find);
361                 printf("元素%d所在位置:%d
",  find,  ds_search(pHead, find));
362                 //ListTraverse(L);
363                 printf("
");
364                 break;
365 
366             case 5:
367                 ds_traverse(pHead);
368                 printf("
");
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结束
");
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("链表中的元素是:
");
439     
440     do
441     {
442         printf("%4d",temp->data);
443         temp = temp->next;
444     }while(temp != pNode);
445     printf("
");
446 }
447 
448 int main(void)
449 {
450     LinkList *pNode;
451     LinkList *L;
452     pNode = initList();   
453     printList(pNode);
454     
455     return 0;
456 }

 

以上是关于线性表:循环链表的主要内容,如果未能解决你的问题,请参考以下文章

线性表:循环链表

线性表实现——双向循环链表

线性表-双向循环链表

第三章 线性表---链式存储结构(循环链表)

数据结构第五篇——线性表的链式存储之循环链表

线性表实现——单向循环链表