[转载 整理]C语言链表实例

  C语言链表有单链表、双向链表、循环链表。单链表由数据域和指针域组成,数据域存放数据,指针域存放该数据类型的指针便于找到下一个节点。双链表则含有头指针域、数据域和尾指针域,域单链表不同,双链表可以从后一个节点找到前一个节点,二单链表则不行。循环链表就是在单链表的基础上,将头结点的地址指针存放在最后一个节点的指针域里以,此形成循环。此外还有双向循环链表,它同时具有双向链表和循环链表的功能。

  单链表如:
  链表节点的数据结构定义
struct node  
{  
    int num;  
    struct node *p;  
} ; 

 在此链表节点的定义中,除一个整型的成员外,成员p是指向与节点类型完全相同的指针。

 ※在链表节点的数据结构中,非常特殊的一点就是结构体内的指针域的数据类型使用了未定义成功的数据类型。这是在C中唯一规定可以先使用后定义的数据结构。

 

链表实例代码:

  1 // 原文地址 http://www.cnblogs.com/wireless-dragon/p/5170565.html
  2 #include<stdio.h>
  3 #include<stdlib.h>
  4 #include<string.h>
  5 
  6 typedef int elemType;//定义存入的数据的类型可以是int char 
  7 
  8 typedef struct NODE{ //定义链表的结构类型
  9     elemType element;
 10     struct NODE *next;
 11 }Node;
 12 
 13 /************************************************************************/
 14 /*             以下是关于线性表链接存储(单链表)操作的19种算法        */
 15 
 16 /* 1.初始化线性表,即置单链表的表头指针为空 */
 17 /* 2.创建线性表,此函数输入负数终止读取数据*/
 18 /* 3.打印链表,链表的遍历*/
 19 /* 4.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
 20 /* 5.返回单链表的长度 */
 21 /* 6.检查单链表是否为空,若为空则返回1,否则返回0 */
 22 /* 7.返回单链表中第pos个结点中的元素,若pos超出范围,则停止程序运行 */
 23 /* 8.从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL */
 24 /* 9.把单链表中第pos个结点的值修改为x的值,若修改成功返回1,否则返回0 */
 25 /* 10.向单链表的表头插入一个元素 */
 26 /* 11.向单链表的末尾添加一个元素 */
 27 /* 12.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0 */
 28 /* 13.向有序单链表中插入元素x结点,使得插入后仍然有序 */
 29 /* 14.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行 */
 30 /* 15.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行 */
 31 /* 16.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行 */
 32 /* 17.从单链表中删除值为x的第一个结点,若删除成功则返回1,否则返回0 */
 33 /* 18.交换2个元素的位置 */
 34 /* 19.将线性表进行冒排序 */
 35 
 36 
 37 
 38 /*注意检查分配到的动态内存是否为空*/
 39 
 40 
 41 
 42 
 43 /* 1.初始化线性表,即置单链表的表头指针为空 */
 44 void initList(Node **pNode)
 45 {
 46     *pNode=NULL;
 47     printf("initList函数执行,初始化成功\n");
 48 }
 49 
 50 /* 2.创建线性表,此函数输入负数终止读取数据*/
 51 Node *creatList(Node *pHead)
 52 {
 53     Node *p1,*p2;
 54     p1=p2=(Node *)malloc(sizeof(Node));
 55     if(p1 == NULL || p2 ==NULL)
 56     {
 57         printf("内存分配失败\n");    
 58         exit(0);
 59     }
 60     memset(p1,0,sizeof(Node));
 61     
 62     scanf("%d",&p1->element);
 63     p1->next=NULL;
 64     
 65     while(p1->element >0)  //输入的值大于0则继续,否则停止
 66     {
 67         if(pHead == NULL)//空表,接入表头
 68         {
 69             pHead=p1;
 70         }
 71         else 
 72         {
 73             p2->next=p1;
 74         }
 75     
 76         p2=p1;
 77         p1=(Node *)malloc(sizeof(Node));
 78     
 79         if(p1==NULL||p2==NULL)
 80         {
 81             printf("内存分配失败\n");
 82             exit(0);
 83         }
 84         memset(p1,0,sizeof(Node));
 85         scanf("%d",&p1->element);
 86         p1->next=NULL;
 87     }
 88     printf("CreatList函数执行,链表创建成功\n");
 89     return pHead;    
 90 }
 91 
 92 /* 3.打印链表,链表的遍历*/
 93 void printList(Node *pHead)
 94 {
 95     if(NULL==pHead)
 96     {
 97         printf("PrintList函数执行,链表为空\n");
 98     }
 99     else
100     {
101         while(NULL!=pHead)
102         {
103             printf("%d\n",pHead->element);
104             pHead=pHead->next;
105         }
106     }
107 
108 }
109 
110 
111 /* 4.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
112 void clearList(Node *pHead)
113 {
114     Node *pNext;
115     
116     if(pHead==NULL)
117     {
118         printf("clearList函数执行,链表为空\n");
119         return;
120     }
121     while(pHead->next!=NULL)
122     {
123         pNext=pHead->next;
124         free(pHead);
125         pHead=pNext;
126     }
127     printf("clearList函数执行,链表已经清除!\n");
128 
129 }
130 
131 /* 5.返回链表的长度*/
132 int sizeList(Node *pHead)
133 {
134     int size=0;
135     
136     while(pHead!=NULL)
137     {
138         size++;
139         pHead=pHead->next;
140     }
141     printf("sizelist函数执行,链表长度为%d\n",size);
142     return size;
143 }
144 
145 /* 6.检查单链表是否为空,若为空则返回1,否则返回0 */
146 int isEmptyList(Node *pHead)
147 {
148     if(pHead==NULL)
149     {
150         printf("isEmptylist函数执行,链表为空!\n");
151         return 1;
152     }
153 
154     else 
155         printf("isEmptylist函数执行,链表非空!\n");
156         return 0;
157 
158 }
159 
160 /* 7.返回链表中第post节点的数据,若post超出范围,则停止程序运行*/
161 int getElement(Node *pHead,int pos)
162 {
163     int i=0;
164     if(pos<1)
165     {
166         printf("getElement函数执行,pos值非法!");
167         return 0;
168     }
169     if(pHead==NULL)
170     {
171         printf("getElement函数执行,链表为空!");
172     }
173 
174     while (pHead!=NULL)
175     {
176         ++i;
177         if(i==pos)
178         {
179             break;
180         }
181         pHead=pHead->next;
182     }    
183     if(i<pos)
184     {
185         printf("getElement函数执行,pos值超出链表长度\n");
186         return 0;        
187     }
188     printf("getElement函数执行,位置%d中的元素为%d\n",pos,pHead->element);
189     
190     return 1;
191 }
192 
193 //8.从单一链表中查找具有给定值x的第一个元素,若查找成功后,返回该节点data域的存储位置,否则返回NULL
194 elemType *getElemAddr(Node *pHead,elemType x)
195 {
196     if(NULL==pHead)
197     {    
198         printf("getEleAddr函数执行,链表为空");
199         return NULL;    
200     }
201     if(x<0)
202     {
203         printf("getEleAddr函数执行,给定值x不合法\n");
204         return NULL;
205     }
206     while((pHead->element!=x)&&(NULL!=pHead->next))//判断链表是否为空,并且是否存在所查找的元素
207     {
208         pHead=pHead->next;
209     }    
210     if(pHead->element!=x)
211     {
212         printf("getElemAddr函数执行,在链表中没有找到x值\n");
213         return NULL;
214     }
215     else
216     {
217         printf("getElemAddr函数执行,元素%d的地址为0x%x\n",x,&(pHead->element));
218     }
219     return &(pHead->element);
220 
221 }    
222 
223 
224 /*9.修改链表中第pos个点X的值,如果修改成功,则返回1,否则返回0*/
225 int modifyElem(Node *pNode,int pos,elemType x)
226 {
227     Node *pHead;
228     pHead=pNode;
229     int i=0;
230     if(NULL==pHead)
231     {
232         printf("modifyElem函数执行,链表为空\n");
233         return 0;
234     }
235     
236     if(pos<1)
237     {
238         printf("modifyElem函数执行,pos值非法\n");
239         return 0;
240     }
241     
242     while(pHead!= NULL)
243     {
244         ++i;
245         if(i==pos)
246         {
247             break;
248         }
249         pHead=pHead->next;
250     }
251     
252     if(i<pos)
253     {
254         printf("modifyElem函数执行,pos值超出链表长度\n");
255         return 0;
256     }
257     pNode=pHead;
258     pNode->element=x;
259     printf("modifyElem函数执行,修改第%d点的元素为%d\n",pos,x);
260 
261     return 1;
262 
263 }
264 
265 /* 10.向单链表的表头插入一个元素 */
266 int insertHeadList(Node **pNode,elemType insertElem)
267 {
268     Node *pInsert;
269     pInsert=(Node *)malloc(sizeof(Node));
270     if(pInsert==NULL)  exit(1);
271     memset(pInsert,0,sizeof(Node));
272     pInsert->element=insertElem;
273     pInsert->next=*pNode;
274     *pNode=pInsert;
275     printf("insertHeadList函数执行,向表头插入元素%d成功\n",insertElem);
276     return 1;
277 }
278 
279 /* 11.向单链表的末尾添加一个元素 */
280 int insertLastList(Node *pNode,elemType insertElem)
281 {
282     Node *pInsert;    
283     Node *pHead;
284     Node *pTmp;
285 
286     pHead=pNode;
287     pTmp=pHead;
288     pInsert=(Node *)malloc(sizeof(Node));
289     if(pInsert==NULL)  exit(1);
290     memset(pInsert,0,sizeof(Node));
291     pInsert->element=insertElem;
292     pInsert->next=NULL;
293     while(pHead->next!=NULL)
294     {
295         pHead=pHead->next;
296     }
297     pHead->next=pInsert;      
298     printf("insertLastList函数执行,向表尾插入元素%d成功!\n",insertElem);
299     return     1;
300 }
301 
302 /* 12.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0*/ 
303 int isAddPos(Node *pNode,int pos,elemType x)
304 {
305     Node *pHead;
306     pHead=pNode;
307     Node *pTmp;
308     int i=0;
309     
310     if(NULL==pHead)
311     {
312         printf("AddPos函数执行,链表为空\n");
313         return 0;
314     }
315     
316     if(pos<1)
317     {
318         printf("AddPos函数执行,pos值非法\n");
319         return 0;
320     }
321     
322     while(pHead!=NULL)
323     {
324         ++i;
325         if(i==pos)
326         break;
327         pHead=pHead->next;
328     }
329     
330     if(i<pos)
331     {
332         printf("AddPos函数执行,pos值超出链表长度\n");
333         return 0;
334     }
335     
336     pTmp=(Node *)malloc(sizeof(Node));
337     if(pTmp==NULL)  exit(1);
338     memset(pTmp,0,sizeof(Node));
339     pTmp->next=pHead->next;
340     pHead->next=pTmp;
341     pTmp->element=x;
342 
343     printf("AddPos函数执行成功,向节点%d后插入数值%d\n",pos,x);
344     return 1;
345 }
346 
347 /* 13.向有序单链表中插入元素x结点,使得插入后仍然有序 */
348 int OrrderList(Node *pNode,elemType x)
349 {
350 //注意如果此数值要排到行尾要修改本代码
351     Node *pHead;
352         pHead=pNode;
353         Node *pTmp;
354         
355         if(NULL==pHead)
356         {
357                 printf("OrrderList函数执行,链表为空\n");
358                 return 0;
359         }
360 
361         if(x<1)
362         {
363                 printf("OrrderList函数执行,x值非法\n");
364                 return 0;
365         }
366 
367         while(pHead!=NULL)
368         {
369                 if((pHead->element)>=x)
370                 break;
371                 pHead=pHead->next;
372         }
373     
374     
375     if(pHead==NULL)   
376     {
377         printf("OrrderList函数查找完毕,该函数中没有该值\n");
378         return 0;
379     }    
380         
381 
382     pTmp=(Node *)malloc(sizeof(Node));
383     if(pTmp==NULL)  exit(1);       
384     memset(pTmp,0,sizeof(Node));
385         pTmp->next=pHead->next;
386         pHead->next=pTmp;
387         pTmp->element=x;
388     
389     printf("OrrderList函数成功插入数值%d\n",x);
390     return 1;
391 }
392 
393 /*14.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行*/
394 int DelHeadList(Node **pList)
395 {
396     Node *pHead;
397     pHead=*pList;
398     if(pHead!=NULL)
399     printf("DelHeadList函数执行,函数首元素为%d删除成功\n",pHead->element);
400     else 
401     {
402         printf("DelHeadList函数执行,链表为空!");
403         return 0;
404     }
405     *pList=pHead->next;
406     return 1;
407 }
408 
409 /* 15.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行 */
410 int DelLastList(Node *pNode)
411 {    
412     Node *pHead;
413     Node *pTmp;
414 
415     pHead=pNode;
416     while(pHead->next!=NULL)
417     {
418         pTmp=pHead;
419         pHead=pHead->next;
420     }
421     printf("链表尾删除元素%d成功!\n",pHead->element);
422     free(pHead);
423     pTmp->next=NULL;
424     return     1;
425 }
426 
427 /* 16.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行 */
428 int DelPos(Node *pNode,int pos)
429 {
430     Node *pHead;
431     pHead=pNode;
432     Node *pTmp;
433 
434     int i=0;
435     
436     if(NULL==pHead)
437     {
438         printf("DelPos函数执行,链表为空\n");
439         return 0;
440     }
441     
442     if(pos<1)
443     {
444         printf("DelPos函数执行,pos值非法\n");
445         return 0;
446     }
447     
448     while(pHead!=NULL)
449     {
450         ++i;
451         if(i==pos)
452         break;
453         pTmp=pHead;
454         pHead=pHead->next;
455     }
456     
457     if(i<pos)
458     {
459         printf("DelPos函数执行,pos值超出链表长度\n");
460         return 0;
461     }
462         printf("DelPos函数执行成功,节点%d删除数值%d\n",pos,pHead->element);
463     pTmp->next=pHead->next;
464     free(pHead);    
465     return 1;
466 }
467 
468 /* 17.从单链表中删除值为x的第一个结点,若删除成功则返回1,否则返回0 */
469 int Delx(Node **pNode,int x)
470 {
471     Node *pHead;
472     Node *pTmp;
473     pHead=*pNode;
474     int i=0;
475             
476     if(NULL==pHead)
477     {    
478         printf("Delx函数执行,链表为空");
479         return 0;    
480     }
481     if(x<0)
482     {
483         printf("Delx函数执行,给定值x不合法\n");
484         return 0;
485     }
486     while((pHead->element!=x)&&(NULL!=pHead->next))//判断链表是否为空,并且是否存在所查找的元素
487     {
488         ++i;
489         pTmp=pHead;    
490         pHead=pHead->next;
491     }    
492     if(pHead->element!=x)
493     {
494         printf("Delx函数执行,在链表中没有找到x值\n");
495         return 0;
496     }
497     if((i==0)&&(NULL!=pHead->next))
498     {
499         printf("Delx函数执行,在链表首部找到此元素,此元素已经被删除\n");
500         *pNode=pHead->next;
501         free(pHead);
502         return 1;
503     }
504     printf("Delx函数执行,首个为%d元素被删除\n",x);
505     pTmp->next=pHead->next;
506     free(pHead);
507     return 1;
508 }
509 
510 /* 18.交换2个元素的位置 */
511 int exchange2pos(Node *pNode,int pos1,int pos2)
512 {
513     Node *pHead;
514     int *pTmp;
515     int *pInsert;
516     int a;
517     int i=0;
518     
519     if(pos1<1||pos2<1)
520         {
521                 printf("DelPos函数执行,pos值非法\n");
522                 return 0;
523         }
524     
525     pHead=pNode;
526         while(pHead!=NULL)
527         {
528                 ++i;
529                 if(i==pos1)
530                 break;
531                 pHead=pHead->next;
532         }
533 
534         if(i<pos1)
535         {
536                 printf("DelPos函数执行,pos1值超出链表长度\n");
537                 return 0;
538         }
539 
540     pTmp=&(pHead->element);
541     i=0;
542     pHead=pNode;
543         while(pHead!=NULL)
544         {
545                 ++i;
546                 if(i==pos2)
547                 break;
548                 pHead=pHead->next;
549         }
550 
551         if(i<pos2)
552         {
553                 printf("DelPos函数执行,pos2值超出链表长度\n");
554                 return 0;
555         }
556 
557     pInsert=&(pHead->element);
558     a=*pTmp;
559     *pTmp=*pInsert;
560     *pInsert=a;
561     
562     printf("DelPos函数执行,交换第%d个和第%d个pos点的值\n",pos1,pos2);
563         return 1;
564 }
565 
566 int swap(int *p1,int *p2)
567 {
568     int a;
569     if(*p1>*p2)
570     {
571         a=*p1;
572         *p1=*p2;
573         *p2=a;
574     }
575     return 0;
576 }
577 
578 /* 19.将线性表进行冒泡排序 */
579 int Arrange(Node *pNode)
580 {
581     Node *pHead;
582         pHead=pNode;
583 
584     int a=0,i,j;
585 
586         if(NULL==pHead)
587         {
588                  printf("Arrange函数执行,链表为空\n");
589                  return 0;
590         }
591         
592     while(pHead!=NULL)
593     {
594         ++a;
595             pHead=pHead->next;
596         }
597      
598     pHead=pNode;
599     for(i=0;i<a-1;i++)
600     {
601         for(j=1;j<a-i;j++)
602         {
603             swap(&(pHead->element),&(pHead->next->element));
604             pHead=pHead->next;
605         }
606         pHead=pNode;
607     }
608     printf("Arrange函数执行,链表排序完毕!\n");
609     return 0;
610 }
611 
612 int main()
613 {
614     Node *pList=NULL;
615     int length=0;
616     
617     elemType posElem;
618     
619     initList(&pList);
620     printList(pList);
621     
622     pList=creatList(pList);
623     printList(pList);
624     
625     sizeList(pList);
626     printList(pList);
627 
628     isEmptyList(pList);
629     
630 
631         posElem=getElement(pList,3);
632     printList(pList);
633     
634     getElemAddr(pList,5);
635 
636     modifyElem(pList,4,1);
637     printList(pList);
638     
639     insertHeadList(&pList,5);
640     printList(pList);
641 
642     insertLastList(pList,10);
643     printList(pList);
644 
645     isAddPos(pList,4,5);
646     printList(pList);
647     
648     OrrderList(pList,6);
649     printList(pList);
650     
651     DelHeadList(&pList);    
652     printList(pList);
653     
654     DelLastList(pList);
655     printList(pList);
656     
657     DelPos(pList,5);
658     printList(pList);
659     
660     Delx(&pList,5);
661     printList(pList);
662     
663     exchange2pos(pList,2,5);
664     printList(pList);
665     
666     Arrange(pList);    
667     printList(pList);
668     
669     clearList(pList);
670     return 0;
671 }

 

posted @ 2016-08-25 16:28  天涯一缕清枫  阅读(3181)  评论(0编辑  收藏  举报