C语言链表实例

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

代码中有些地方没有考虑到的,希望大家补充完善!

时间: 2024-08-25 18:54:24

C语言链表实例的相关文章

C语言链表实例--玩转链表

下图为最一简单链表的示意图: 第 0 个结点称为头结点,它存放有第一个结点的首地址,它没有数据,只是一个指针变量.以下的每个结点都分为两个域,一个是数据域,存放各种实际的数据,如学号 num,姓名 name,性别 sex 和成绩 score 等.另一个域为指针域,存放下一结点的首地址.链表中的每一个结点都是同一种结构类型. 指针域: 即在结点结构中定义一个成员项用来存放下一结点的首地址,这个用于存放地址的成员,常把它称为指针域. 在第一个结点的指针域内存入第二个结点的首地址,在第二个结点的指针域

c语言链表和指针的运用

在学习指针之前,首先要认识指针.指针是一个存储计算机内存地址的变量.从指针指向的内存读取数据称作指针的取值.指针可以指向某些具体类型的变量地址,例如int.long和double.指针也可以是void类型.NULL指针和未初始化指针. 根据出现的位置不同,操作符 * 既可以用来声明一个指针变量,也可以用作指针的取值.当用在声明一个变量时,*表示这里声明了一个指针.其它情况用到*表示指针的取值.&是地址操作符,用来引用一个内存地址.通过在变量名字前使用&操作符,我们可以得到该变量的内存地址.

C语言-链表

单向链表:结构体非常适合链表结构,链表的组成:head指针.数据块节点指针p->nest.结束指针NULL. 链表操作:需要首先找到表头head指针.链表的操作包括动态链表的创建.顺序输出.删除节点.插入节点的操作. 动态存储操作函数:(ANSI规则返回的指针类型为void*,早期的为字符型指针) 分配一个块:void *malloc(unsigned int size)  //分配成功则返回指向起始地址的指针void * 分配多个块:void *calloc(unsigned n,unsign

C语言优化实例:消除多级指针的间接访问

如果一个多层次的数据结构达到两级或者两级以上,举例如下: struct A{ int array_member[100]; //其他数据成员 }; struct B{ struct A *a_ptr; //其他数据成员 } 那么通过B类型的指针b_ptr访问A类型的array_member的某一个元素array_member[0]则需要使用b_ptr->a_ptr->array_member[0]这种多级指针的形式.如果一个函数中多次用到这个变量的话,可以采用一个临时变量保存这个多级指针:in

C语言优化实例:循环中减少判断

为了让编译器更好地优化循环,应该尽量让循环中减少判断,方法之一是将判断语句整合进表达式.还是这个例子: for (int i = 0; i < 1000*10; i++) { sum += data[i/1000][i%10]; } 假如我们需要加一个判断,只有非负整数才需要作求和运算: for (int i = 0; i < 1000*10; i++) { if (data[i/1000][i%10] >= 0) sum += data[i/1000][i%10]; } 下面将这个判断

关于c语言链表的操作

这几天又讲到链表了,但是又忘记了,所以重新把关于链表的建链表,对链表进行排序,然后是删除,插入,以及遍历等功能..但是最近要考试了,所以没有写成菜单的形式..等考试完了,在进行补充吧.. 代码如下... #include<stdio.h> #include<stdlib.h> #include<string.h> struct node { int data; struct node *next; }; int main() { /*建立链表操作*/ int n,x,p

C语言链表的来源分析

C语言中的链表是重点,也是难点,而且意义非凡.对链表的的抽象和恐惧是源于对它的来龙去脉的不明白.所以很有必要对它的发展渊源做透彻分析. 链表的单位是节点,而节点源于复合数据类型:结构体: 节点和结构体的区别就是看是否有指针域,目的就是想找到下一个节点: 结构体形如: struct Ghost { char name[30]; int age; int height; char addr[30]; }; 节点形如: struct Ghost { char name[30]; int age; in

基于QT的异质链表实例

所谓的异质链表就是的节点元素类型可以不同.本实例采用C++抽象类和多态实现. #include <QApplication> #include<QPushButton> #include<QLabel> // 基类 class base { public: virtual void show()=0; }; //异质链表 class LinkList { private: struct Node { base *pb;//数据域指针 Node *next; }; Nod

注释最全的C语言链表的增删改查

1 //这是C语言的写法,但会报错,原因是len(当前的节点长度) 2 //无法在insert(插入)和deleted(删除)之后改变 3 //不能使用delete是因为delete是C++中的一个运算符 4 //最终我把改程序用C++写了一遍,运用引用将len的真实值改变了 5 #include <stdio.h> 6 #include <stdlib.h> 7 typedef int ElementType; 8 typedef struct node { 9 ElementT