单链表-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指向头结点
单链表-18个基本操作代码实现C语言的更多相关文章
- 数据结构5: 链表(单链表)的基本操作及C语言实现
逻辑结构上一个挨一个的数据,在实际存储时,并没有像顺序表那样也相互紧挨着.恰恰相反,数据随机分布在内存中的各个位置,这种存储结构称为线性表的链式存储. 由于分散存储,为了能够体现出数据元素之间的逻辑关 ...
- 循环单链表定义初始化及创建(C语言)
#include <stdio.h> #include <stdlib.h> /** * 含头节点循环单链表定义,初始化 及创建 */ #define OK 1; #defin ...
- 【数据结构】单链表&&静态链表详解和代码实例
喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 01 单链表(Singly Linked List ) 1.1 什么是单链表? 单链表是一种链式存储的结构.它动态的为节点分配存 ...
- 【线性表基础】顺序表和单链表的插入、删除等基本操作【Java版】
本文表述了线性表及其基本操作的代码[Java实现] 参考书籍 :<数据结构 --Java语言描述>/刘小晶 ,杜选主编 线性表需要的基本功能有:动态地增长或收缩:对线性表的任何数据元素进行 ...
- C代码实现非循环单链表
C代码实现非循环单链表, 直接上代码. # include <stdio.h> # include <stdlib.h> # include <malloc.h> ...
- 单链表反转的原理和python代码实现
链表是一种基础的数据结构,也是算法学习的重中之重.其中单链表反转是一个经常会被考察到的知识点. 单链表反转是将一个给定顺序的单链表通过算法转为逆序排列,尽管听起来很简单,但要通过算法实现也并不是非常容 ...
- 单链表及基本操作(C语言)
#include <stdio.h> #include <stdlib.h> /** * 含头节点单链表定义及基本操作 */ //基本操作函数用到的状态码 #define TR ...
- 数据结构——Java实现单链表
一.分析 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点由元素和指针构成.在Java中,我们可以将单链表定义成一个类,单链表的基 ...
- C# 数据结构--单链表
什么是单链表 这两天看到很多有关单链表的面试题,对单链表都不知道是啥的我.经过学习和整理来分享一下啥是单链表和单链表的一些基本使用方法.最后看些网上有关单链表的面试题代码实例. 啥是单链表? 单链表是 ...
- 数据结构(一) 单链表的实现-JAVA
数据结构还是很重要的,就算不是那种很牛逼的,但起码得知道基础的东西,这一系列就算是复习一下以前学过的数据结构和填补自己在这一块的知识的空缺.加油.珍惜校园中自由学习的时光.按照链表.栈.队列.排序.数 ...
随机推荐
- 为什么不推荐使用Linq?
相信很多.NETer看了标题,都会忍不住好奇,点进来看看,并且顺便准备要喷作者! 这里,首先要申明一下,作者本人也非常喜欢Linq,也在各个项目中常用Linq. 我爱Linq,Linq优雅万岁!!!( ...
- ClickHouse介绍(四)ClickHouse使用操作
ClickHouse使用操作 这章主要介绍在ClickHouse使用的各个操作的注意点.常规的统一语法不做详细介绍. 1. Join操作 在ClickHouse中,对连接操作定义了不同的精度,包含AL ...
- Linux创建新用户时遇到的问题记录
创建新用户命令: useradd -d "/home/guest" -m -s "/bin/bash" guest 报错: useradd: cannot op ...
- 时间序列分析专题——利用SPSS专家建模器进行建模
SPSS的专家建模器可以自动识别数据,给出最适合的模型,本章通过三个例题介绍如何使用SPSS实现时间序列分析.由于本人对时间序列分析的理解尚浅,做出模型后在论文上的呈现形式需要取查阅资料,以便更好地在 ...
- nuxt3正确使用keepalive页面缓存组件缓存
最近使用nuxt@3.x版本做SEO优化项目比较多,之前也踩坑过,所以记录一下在 nuxt3 中路由缓存的正确使用方法,本人也之前在GitHub社区中提交过反馈问题,最后是在 3.8.2 版本解决了路 ...
- 国产开源存储之光:Curve 通过信创认证
网易数帆喜讯再传,Curve 近日通过信息技术应用创新(信创)认证! Curve 是一款高性能.易运维.云原生的分布式存储系统,由网易数帆存储团队发起开源,现为 CNCF 沙箱项目.国家工业信息安全发 ...
- oeasy教您玩转vim - 28 - 水平移动
水平移动 回忆上节课内容 根据扩展名我们可以设置某些特定类型文件的配置 相关文件类型的设置放在相应的文件夹里 文件类型缩进文件夹 /usr/share/vim/vim81/indent/ 文件类型 ...
- 题解:P10723 [GESP202406 七级] 黑白翻转
背景 汗流浃背了. 分析 容易想到一个显然的思路:以任意节点为根,开始遍历.如果一个节点的子树里面有黑点,那么它必须保留,否则如果它是白点,则可以删去. 但这个方法很容易举出反例: 在这颗树中,如果以 ...
- P2427 题解
洛谷链接 题目简述 给定 \(N \times M\) 的字符矩阵,有 \(Q\) 次询问,对于每次询问给出 \(x,y\),求以 \((x,y)\) 为中心的最大正方形边长且正方形中字符均相同. 思 ...
- AT_arc149_a 题解
洛谷链接&Atcoder 链接 本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读. 题目简述 求满足以下条件的小于 \(10 ^ n\) 数最大是多少? 每一位数字均相同: 是 \ ...