单链表-18个基本操作代码实现C语言

单链表-18个基本操作代码实现C语言

原文地址:https://www.cnblogs.com/actanble/p/6713434.html

无更改,仅复现

 

运行后如图,运行软件dev-C++,系统版本win10

 

 

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

 

总结:

进一步理解怎样构造函数、调用、函数之间的关系。

memset函数与L=(linklist)malloc(sizeof(Node))作用?

malloc函数:

L=(linklist)malloc(sizeof(Node))作用是生成一个新结点做头结点,头指针L指向头结点

memset函数:
void * memset (void * p,int c,size_t n);
其中,指针p为所操作的内存空间的首地址,c为每个字节所赋的值,n为所操作内存空间的字节长度,也就是内存被赋值为c的字节数。
在使用memset时经常要注意的它是以字节为单位进行赋值的,所赋值的范围是0x00~0xFF。若想要对一个double或int型的数组赋值时,就特别需要注意这一点:
 
 
 
posted @ 2020-04-28 00:08  raodiqiu  阅读(1561)  评论(0编辑  收藏  举报