c语言单链表应用(城市坐标)
- 格式:docx
- 大小:13.02 KB
- 文档页数:3
c链表库函数全文共四篇示例,供读者参考第一篇示例:C语言是一种广泛应用于系统编程的高级语言,而链表(Linked List)是C语言中常用的数据结构之一。
在C语言中,链表并不像数组一样有现成的库函数可以直接调用,需要通过自定义函数来实现链表的操作。
为了方便使用链表,不少开发者封装了链表操作的库函数,提供了一些常用的链表操作接口,以供开发者使用。
本文将介绍一些常见的C链表库函数及其用法。
一、链表的概念及基本操作链表是一种线性表的存储结构,由若干节点(Node)组成,每个节点包含数据域和指针域。
数据域用于存放数据,指针域用于指向下一个节点。
链表的最后一个节点指针域为空(NULL),表示链表的末尾。
常见的链表操作包括创建链表、插入节点、删除节点、遍历链表、查找节点等。
下面我们来看看C语言中常用的链表库函数。
二、常见的C链表库函数1. 创建链表在C语言中,创建链表的函数通常包括初始化链表头节点和链表节点的操作。
```#include <stdio.h>#include <stdlib.h>//定义链表节点typedef struct node {int data;struct node* next;} Node;2. 插入节点插入节点是链表操作中的重要操作,可以在链表的任意位置插入新节点。
常见的插入方式包括头部插入和尾部插入。
```//头部插入节点void insertNodeAtHead(Node* head, int data) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = data;newNode->next = head->next;head->next = newNode;}以上是常见的C链表库函数,这些函数可以帮助我们更方便地操作链表。
在实际开发中,可以根据需要自定义更多的链表操作函数,以满足具体的需求。
单链表(c语⾔实现)贼详细直接上代码吧#include<stdio.h>#include<malloc.h>/*单链表特点:它是⼀种动态的储存结构,链表中每个节点占⽤的储存空间不是预先分配的,⽽是运⾏时系统根据需求⽣成的*/typedef struct lnode{int data;struct lnode *next;}lnode,*linklist;//结点定义/*关于头指针的⼀点说明:linklist L;外⾯⽤头指针来标识⼀个单链表,如单链表L,单链表H等,是指链表的第⼀个节点的地址被记录在指针变量L,H中,头指针为NULL时,表⽰⼀个空的单链表,需要进⼀步指出的是:上⾯定义的lnode是节点的类型,linklist是指向lnode节点的指针的类型,为了增强程序的可读性,通常将标识⼀个链表的头指针说明为linklist类型的变量*/linklist creat_linklist_insert_head_nohead(){linklist l=NULL;//定义头指针变量llnode *s;//新建⼀个节点int flag=-1;//输⼊停⽌标志位printf("输⼊整型数据,数据以空格隔开,输⼊数据为-1的时候表⽰输⼊截⽌\n");while(1){int x;scanf("%d",&x);if(x==flag)break;s=(lnode*)malloc(sizeof(lnode));//对s节点申请储存空间s->data=x;//赋值s->next=l;//s节点的next指向头指针l=s;//头指针指向新建⽴的s节点,因为这是在单链表的头部插⼊数据}return l;}//创建⼀个单链表,通过在头部插⼊数据,不含空的头节点//-------------------------------------------------------------------------------------------------------------///*在单链表的表头插⼊,只要x!=flag,就是⼀直申请s结点,从⽽可以⼀直在表头插⼊,其中l=s是最重要的,因为这是将s插⼊到l的表头,因为是在头部插⼊,所以只要⼀个头指针就可以,若是在单链表的尾部插⼊,那么就需要尾部指针关于此函数使⽤的⼀点说明:我们输⼊数据 1 2 3 4 5的时候,输出的是 5 4 3 2 1,因为我们是在头部插⼊数据的*///-------------------------------------------------------------------------------------------------------------//linklist creat_linklist_insert_end_yeshead(){linklist l=NULL,r=NULL;//定义头指针变量和尾指针变量lnode *s;//定义新建节点int flag=-1;//输⼊结束标志位printf("输⼊整型数据,数据以空格隔开,输⼊数据为-1的时候表⽰输⼊截⽌\n");while(1){int x;scanf("%d",&x);if(x==flag)//输⼊数据等于输⼊结束标志位则跳出循环break;s=(lnode*)malloc(sizeof(lnode));//申请内存空间s->data=x;//赋值if(l==NULL)//单链表为空l=s;//则将头指针指向新建节点elser->next=s;//不空的话则将尾指针的next指向s,因为如果不空的话,尾指针指向的肯定是⼀个数据节点,尾指针的next指向s是为了将两个数据节点连接起来r=s;//尾指针移动到新插⼊的节点上}if(r!=NULL)//有数据r->next=NULL;//尾指针的next指向空,说明尾指针后⾯没有数据了,⽬的的为了保证单链表尾指针逻辑的合理性return l;}//建⽴单链表且在链表尾部插⼊数据,含空的头节点//-----------------------------------------------------------------------------------------------------------------------///*在单链表的尾部插⼊,只要没有输⼊结束的标志,就⼀直申请s结点,然后把x赋给s结点的data域,l=s是为了第⼀个结点的结点的处理,因为在此之前l是⼀个空表,然后因为不断有新的结点⽣成,所以就是不断把新的s结点赋给r的next,这样就不断有s结点加⼊到了单链表中间,然后最重要的是每次新的结点加⼊到单链表中后要把r尾指针向后⾯移动,就是⽂中的r=s;关于此函数的⼀点说明:输⼊数据 1 2 3 4 5,输出还是 1 2 3 4 5,⽽不是 5 4 3 2 1,因为我们插⼊数据是在链表尾部插⼊的*///-----------------------------------------------------------------------------------------------------------------------//int length_linklist_yeshead(linklist l){linklist p=l;int j=1;while(p->next){j++;p=p->next;}return j;}//求单链表的表长,针对含有空的头节点的单链表int length_linklist_nohead(linklist l){lnode *p=l;int j=0;while(p){j++;p=p->next;}return j;}//求链表的表长,针对不含空的头节点的单链表lnode *get_linklist(linklist l,int i){lnode *p=l;int j=0;while(p!=NULL&&j<i){p=p->next;j++;}if(j==i)return p;elsereturn NULL;}//单链表的查找第i个元素结点,*p=l就是使p指针指向l链表;lnode *locate_linklist(linklist l,int x){lnode *p=l->next;//l为头节点while(p!=NULL&&p->data!=x)p=p->next;return p;}//单链表查找值为x的结点,找到后返回指向这个结点的指针;以后时刻要记得l为头指针,因为定义了头指针⽐没有定义头指针要⽅便许多;int insert_linklist(linklist l,int i,int x){lnode *p,*s;p=get_linklist(l,i-1);//找到第i-1个结点if(p==NULL){printf("i错误");return0;}elses=(lnode*)malloc(sizeof(lnode));s->data=x;s->next=p->next;p->next=s;return1;}//单链表的第i个结点后⾯的插⼊,重要的是申请,封装s结点,int del_linklist(linklist l,int i){i--;linklist p,s;p=get_linklist(l,i-1);if(p==NULL){printf("该i-1节点不存在");return -1;}else if(p->next==NULL){printf("第i个结点不存在");return0;}else{s=p->next;p->next=s->next;free(s);return1;}}//单链表中删除第i个结点,那么就先要找到i个结点的前驱,也就是第i-1个结点,同理单链表中的插⼊也要知道其前驱结点,所以单链表中的头节点的重要性就可想⽽知了void printf_linklist(lnode *plisthead){lnode *ptemp=plisthead;while(ptemp){printf("%d\t",ptemp->data);ptemp=ptemp->next;}printf("\n");}//链表打印函数int main(){/*linklist l=creat_linklist_insert_end_yeshead();printf("%d\n",length_linklist_yeshead(l));insert_linklist(l,2,100);//第⼆个结点的后⾯插⼊100printf_linklist(l);del_linklist(l,4);//删除第四个结点printf_linklist(l);*//*linklist l=creat_linklist_insert_head_nohead();printf("%d\n",length_linklist_nohead(l));insert_linklist(l,2,100);printf_linklist(l);del_linklist(l,4);printf_linklist(l);*/return0;}。
[转载整理]C语⾔链表实例 C语⾔链表有单链表、双向链表、循环链表。
单链表由数据域和指针域组成,数据域存放数据,指针域存放该数据类型的指针便于找到下⼀个节点。
双链表则含有头指针域、数据域和尾指针域,域单链表不同,双链表可以从后⼀个节点找到前⼀个节点,⼆单链表则不⾏。
循环链表就是在单链表的基础上,将头结点的地址指针存放在最后⼀个节点的指针域⾥以,此形成循环。
此外还有双向循环链表,它同时具有双向链表和循环链表的功能。
单链表如:链表节点的数据结构定义struct node{int num;struct node *p;} ;在此链表节点的定义中,除⼀个整型的成员外,成员p是指向与节点类型完全相同的指针。
※在链表节点的数据结构中,⾮常特殊的⼀点就是结构体内的指针域的数据类型使⽤了未定义成功的数据类型。
这是在C中唯⼀规定可以先使⽤后定义的数据结构。
链表实例代码:1// 原⽂地址 /wireless-dragon/p/5170565.html2 #include<stdio.h>3 #include<stdlib.h>4 #include<string.h>56 typedef int elemType;//定义存⼊的数据的类型可以是int char78 typedef struct NODE{ //定义链表的结构类型9 elemType element;10struct NODE *next;11 }Node;1213/************************************************************************/14/* 以下是关于线性表链接存储(单链表)操作的19种算法 */1516/* 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.将线性表进⾏冒排序 */35363738/*注意检查分配到的动态内存是否为空*/3940414243/* 1.初始化线性表,即置单链表的表头指针为空 */44void initList(Node **pNode)45 {46 *pNode=NULL;47 printf("initList函数执⾏,初始化成功\n");48 }4950/* 2.创建线性表,此函数输⼊负数终⽌读取数据*/51 Node *creatList(Node *pHead)52 {53 Node *p1,*p2;54 p1=p2=(Node *)malloc(sizeof(Node));55if(p1 == NULL || p2 ==NULL)57 printf("内存分配失败\n");58 exit(0);59 }60 memset(p1,0,sizeof(Node));6162 scanf("%d",&p1->element);63 p1->next=NULL;6465while(p1->element >0) //输⼊的值⼤于0则继续,否则停⽌66 {67if(pHead == NULL)//空表,接⼊表头68 {69 pHead=p1;70 }71else72 {73 p2->next=p1;74 }7576 p2=p1;77 p1=(Node *)malloc(sizeof(Node));7879if(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");89return pHead;90 }9192/* 3.打印链表,链表的遍历*/93void printList(Node *pHead)94 {95if(NULL==pHead)96 {97 printf("PrintList函数执⾏,链表为空\n");98 }99else100 {101while(NULL!=pHead)102 {103 printf("%d\n",pHead->element);104 pHead=pHead->next;105 }106 }107108 }109110111/* 4.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为⼀个空表 */ 112void clearList(Node *pHead)113 {114 Node *pNext;115116if(pHead==NULL)117 {118 printf("clearList函数执⾏,链表为空\n");119return;120 }121while(pHead->next!=NULL)122 {123 pNext=pHead->next;124free(pHead);125 pHead=pNext;126 }127 printf("clearList函数执⾏,链表已经清除!\n");128129 }130131/* 5.返回链表的长度*/132int sizeList(Node *pHead)133 {134int size=0;135136while(pHead!=NULL)137 {138 size++;139 pHead=pHead->next;141 printf("sizelist函数执⾏,链表长度为%d\n",size);142return size;143 }144145/* 6.检查单链表是否为空,若为空则返回1,否则返回0 */146int isEmptyList(Node *pHead)147 {148if(pHead==NULL)149 {150 printf("isEmptylist函数执⾏,链表为空!\n");151return1;152 }153154else155 printf("isEmptylist函数执⾏,链表⾮空!\n");156return0;157158 }159160/* 7.返回链表中第post节点的数据,若post超出范围,则停⽌程序运⾏*/161int getElement(Node *pHead,int pos)162 {163int i=0;164if(pos<1)165 {166 printf("getElement函数执⾏,pos值⾮法!");167return0;168 }169if(pHead==NULL)170 {171 printf("getElement函数执⾏,链表为空!");172 }173174while (pHead!=NULL)175 {176 ++i;177if(i==pos)178 {179break;180 }181 pHead=pHead->next;182 }183if(i<pos)184 {185 printf("getElement函数执⾏,pos值超出链表长度\n");186return0;187 }188 printf("getElement函数执⾏,位置%d中的元素为%d\n",pos,pHead->element);189190return1;191 }192193//8.从单⼀链表中查找具有给定值x的第⼀个元素,若查找成功后,返回该节点data域的存储位置,否则返回NULL 194 elemType *getElemAddr(Node *pHead,elemType x)195 {196if(NULL==pHead)197 {198 printf("getEleAddr函数执⾏,链表为空");199return NULL;200 }201if(x<0)202 {203 printf("getEleAddr函数执⾏,给定值x不合法\n");204return NULL;205 }206while((pHead->element!=x)&&(NULL!=pHead->next))//判断链表是否为空,并且是否存在所查找的元素207 {208 pHead=pHead->next;209 }210if(pHead->element!=x)211 {212 printf("getElemAddr函数执⾏,在链表中没有找到x值\n");213return NULL;214 }215else216 {217 printf("getElemAddr函数执⾏,元素%d的地址为0x%x\n",x,&(pHead->element));218 }219return &(pHead->element);220221 }222223224/*9.修改链表中第pos个点X的值,如果修改成功,则返回1,否则返回0*/225int modifyElem(Node *pNode,int pos,elemType x)226 {227 Node *pHead;228 pHead=pNode;229int i=0;230if(NULL==pHead)231 {232 printf("modifyElem函数执⾏,链表为空\n");233return0;234 }235236if(pos<1)237 {238 printf("modifyElem函数执⾏,pos值⾮法\n");239return0;240 }241242while(pHead!= NULL)243 {244 ++i;245if(i==pos)246 {247break;248 }249 pHead=pHead->next;250 }251252if(i<pos)253 {254 printf("modifyElem函数执⾏,pos值超出链表长度\n");255return0;256 }257 pNode=pHead;258 pNode->element=x;259 printf("modifyElem函数执⾏,修改第%d点的元素为%d\n",pos,x);260261return1;262263 }264265/* 10.向单链表的表头插⼊⼀个元素 */266int insertHeadList(Node **pNode,elemType insertElem)267 {268 Node *pInsert;269 pInsert=(Node *)malloc(sizeof(Node));270if(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);276return1;277 }278279/* 11.向单链表的末尾添加⼀个元素 */280int insertLastList(Node *pNode,elemType insertElem)281 {282 Node *pInsert;283 Node *pHead;284 Node *pTmp;285286 pHead=pNode;287 pTmp=pHead;288 pInsert=(Node *)malloc(sizeof(Node));289if(pInsert==NULL) exit(1);290 memset(pInsert,0,sizeof(Node));291 pInsert->element=insertElem;292 pInsert->next=NULL;293while(pHead->next!=NULL)294 {295 pHead=pHead->next;296 }297 pHead->next=pInsert;298 printf("insertLastList函数执⾏,向表尾插⼊元素%d成功!\n",insertElem);299return1;300 }301302/* 12.向单链表中第pos个结点位置插⼊元素为x的结点,若插⼊成功返回1,否则返回0*/ 303int isAddPos(Node *pNode,int pos,elemType x)304 {305 Node *pHead;306 pHead=pNode;307 Node *pTmp;308int i=0;309310if(NULL==pHead)311 {312 printf("AddPos函数执⾏,链表为空\n");313return0;314 }315316if(pos<1)317 {318 printf("AddPos函数执⾏,pos值⾮法\n");319return0;320 }321322while(pHead!=NULL)323 {324 ++i;325if(i==pos)326break;327 pHead=pHead->next;328 }329330if(i<pos)331 {332 printf("AddPos函数执⾏,pos值超出链表长度\n");333return0;334 }335336 pTmp=(Node *)malloc(sizeof(Node));337if(pTmp==NULL) exit(1);338 memset(pTmp,0,sizeof(Node));339 pTmp->next=pHead->next;340 pHead->next=pTmp;341 pTmp->element=x;342343 printf("AddPos函数执⾏成功,向节点%d后插⼊数值%d\n",pos,x); 344return1;345 }346347/* 13.向有序单链表中插⼊元素x结点,使得插⼊后仍然有序 */348int OrrderList(Node *pNode,elemType x)349 {350//注意如果此数值要排到⾏尾要修改本代码351 Node *pHead;352 pHead=pNode;353 Node *pTmp;354355if(NULL==pHead)356 {357 printf("OrrderList函数执⾏,链表为空\n");358return0;359 }360361if(x<1)362 {363 printf("OrrderList函数执⾏,x值⾮法\n");364return0;365 }366367while(pHead!=NULL)368 {369if((pHead->element)>=x)370break;371 pHead=pHead->next;372 }373374375if(pHead==NULL)376 {377 printf("OrrderList函数查找完毕,该函数中没有该值\n");378return0;379 }380381382 pTmp=(Node *)malloc(sizeof(Node));383if(pTmp==NULL) exit(1);384 memset(pTmp,0,sizeof(Node));385 pTmp->next=pHead->next;386 pHead->next=pTmp;387 pTmp->element=x;388389 printf("OrrderList函数成功插⼊数值%d\n",x);390return1;391 }392393/*14.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停⽌程序运⾏*/ 394int DelHeadList(Node **pList)395 {396 Node *pHead;397 pHead=*pList;398if(pHead!=NULL)399 printf("DelHeadList函数执⾏,函数⾸元素为%d删除成功\n",pHead->element); 400else401 {402 printf("DelHeadList函数执⾏,链表为空!");403return0;404 }405 *pList=pHead->next;406return1;407 }408409/* 15.从单链表中删除表尾结点并返回它的值,若删除失败则停⽌程序运⾏ */410int DelLastList(Node *pNode)411 {412 Node *pHead;413 Node *pTmp;414415 pHead=pNode;416while(pHead->next!=NULL)417 {418 pTmp=pHead;419 pHead=pHead->next;420 }421 printf("链表尾删除元素%d成功!\n",pHead->element);422free(pHead);423 pTmp->next=NULL;424return1;425 }426427/* 16.从单链表中删除第pos个结点并返回它的值,若删除失败则停⽌程序运⾏ */ 428int DelPos(Node *pNode,int pos)429 {430 Node *pHead;431 pHead=pNode;432 Node *pTmp;433434int i=0;435436if(NULL==pHead)437 {438 printf("DelPos函数执⾏,链表为空\n");439return0;440 }441442if(pos<1)443 {444 printf("DelPos函数执⾏,pos值⾮法\n");445return0;446 }447448while(pHead!=NULL)449 {450 ++i;451if(i==pos)452break;453 pTmp=pHead;454 pHead=pHead->next;455 }456457if(i<pos)458 {459 printf("DelPos函数执⾏,pos值超出链表长度\n");460return0;461 }462 printf("DelPos函数执⾏成功,节点%d删除数值%d\n",pos,pHead->element); 463 pTmp->next=pHead->next;464free(pHead);465return1;466 }467468/* 17.从单链表中删除值为x的第⼀个结点,若删除成功则返回1,否则返回0 */469int Delx(Node **pNode,int x)470 {471 Node *pHead;472 Node *pTmp;473 pHead=*pNode;474int i=0;475476if(NULL==pHead)477 {478 printf("Delx函数执⾏,链表为空");479return0;480 }481if(x<0)482 {483 printf("Delx函数执⾏,给定值x不合法\n");484return0;485 }486while((pHead->element!=x)&&(NULL!=pHead->next))//判断链表是否为空,并且是否存在所查找的元素487 {488 ++i;489 pTmp=pHead;490 pHead=pHead->next;491 }492if(pHead->element!=x)493 {494 printf("Delx函数执⾏,在链表中没有找到x值\n");495return0;496 }497if((i==0)&&(NULL!=pHead->next))498 {499 printf("Delx函数执⾏,在链表⾸部找到此元素,此元素已经被删除\n");500 *pNode=pHead->next;501free(pHead);502return1;503 }504 printf("Delx函数执⾏,⾸个为%d元素被删除\n",x);505 pTmp->next=pHead->next;506free(pHead);507return1;508 }509510/* 18.交换2个元素的位置 */511int exchange2pos(Node *pNode,int pos1,int pos2)512 {513 Node *pHead;514int *pTmp;515int *pInsert;516int a;517int i=0;518519if(pos1<1||pos2<1)520 {521 printf("DelPos函数执⾏,pos值⾮法\n");522return0;523 }524525 pHead=pNode;526while(pHead!=NULL)527 {528 ++i;529if(i==pos1)530break;531 pHead=pHead->next;532 }533534if(i<pos1)535 {536 printf("DelPos函数执⾏,pos1值超出链表长度\n");537return0;538 }539540 pTmp=&(pHead->element);541 i=0;542 pHead=pNode;543while(pHead!=NULL)544 {545 ++i;546if(i==pos2)547break;548 pHead=pHead->next;549 }550551if(i<pos2)552 {553 printf("DelPos函数执⾏,pos2值超出链表长度\n");554return0;555 }556557 pInsert=&(pHead->element);558 a=*pTmp;559 *pTmp=*pInsert;560 *pInsert=a;561562 printf("DelPos函数执⾏,交换第%d个和第%d个pos点的值\n",pos1,pos2); 563return1;564 }565566int swap(int *p1,int *p2)567 {568int a;569if(*p1>*p2)570 {571 a=*p1;572 *p1=*p2;573 *p2=a;574 }575return0;576 }577578/* 19.将线性表进⾏冒泡排序 */579int Arrange(Node *pNode)580 {581 Node *pHead;582 pHead=pNode;583584int a=0,i,j;585586if(NULL==pHead)587 {588 printf("Arrange函数执⾏,链表为空\n");589return0;590 }591592while(pHead!=NULL)593 {594 ++a;595 pHead=pHead->next;596 }597598 pHead=pNode;599for(i=0;i<a-1;i++)600 {601for(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");609return0;610 }611612int main()613 {614 Node *pList=NULL;615int length=0;616617 elemType posElem;618619 initList(&pList);620 printList(pList);621622 pList=creatList(pList);623 printList(pList);624625 sizeList(pList);626 printList(pList);627628 isEmptyList(pList);629630631 posElem=getElement(pList,3);632 printList(pList);633634 getElemAddr(pList,5);635636 modifyElem(pList,4,1);637 printList(pList);638639 insertHeadList(&pList,5);640 printList(pList);641642 insertLastList(pList,10);643 printList(pList);644645 isAddPos(pList,4,5); 646 printList(pList);647648 OrrderList(pList,6);649 printList(pList);650651 DelHeadList(&pList); 652 printList(pList);653654 DelLastList(pList);655 printList(pList);656657 DelPos(pList,5);658 printList(pList);659660 Delx(&pList,5);661 printList(pList);662663 exchange2pos(pList,2,5); 664 printList(pList);665666 Arrange(pList);667 printList(pList);668669 clearList(pList);670return0;671 }。
单链表的基本操作(C语言)什么是单链表单链表(Singly Linked List)是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。
每个节点只能访问其后继节点,而无法直接访问前驱节点。
单链表的特点是可以动态地插入和删除节点,相比于数组,具有更好的灵活性和扩展性。
在C语言中,我们可以使用指针来实现单链表。
单链表的基本操作1. 定义单链表结构体在C语言中,我们首先需要定义一个表示单链表的结构体。
结构体包含两个成员:数据元素和指向下一个节点的指针。
typedef struct Node {int data; // 数据元素struct Node *next; // 指向下一个节点的指针} Node;2. 创建单链表创建一个空的单链表需要进行以下步骤:•定义头节点,并初始化为NULL。
•向链表中插入新的节点。
Node* createLinkedList() {Node *head = NULL; // 头节点初始化为NULLint n; // 节点数量printf("请输入要创建的节点数量:");scanf("%d", &n);for (int i = 0; i < n; i++) {int data;printf("请输入第%d个节点的值:", i + 1);scanf("%d", &data);Node *newNode = (Node*)malloc(sizeof(Node)); // 创建新节点newNode->data = data;newNode->next = NULL;if (head == NULL) {head = newNode; // 如果是第一个节点,将其设置为头节点 } else {Node *temp = head;while (temp->next != NULL) {temp = temp->next; // 移动到链表末尾}temp->next = newNode; // 将新节点插入到链表末尾}}return head;}3. 插入节点在单链表中插入一个新的节点需要进行以下步骤:•创建一个新的节点。
#include 〈stdio.h>#include <malloc。
h>#include 〈stdlib.h>/*数据结构C语言版线性表的单链表存储结构表示和实现P28—31编译环境:Dev-C++ 4。
9。
9。
2日期:2011年2月10日*/typedef int ElemType;// 线性表的单链表存储结构typedef struct LNode{ElemType data; //数据域struct LNode *next;//指针域}LNode, *LinkList;// typedef struct LNode *LinkList;// 另一种定义LinkList的方法// 构造一个空的线性表Lint InitList(LinkList *L){/*产生头结点L,并使L指向此头结点,头节点的数据域为空,不放数据的。
void *malloc(size_t)这里对返回值进行强制类型转换了,返回值是指向空类型的指针类型.*/(*L)= (LinkList)malloc(sizeof(struct LNode) );if( !(*L))exit(0);// 存储分配失败(*L)-〉next = NULL;// 指针域为空return 1;}// 销毁线性表L,将包括头结点在内的所有元素释放其存储空间。
int DestroyList(LinkList *L){LinkList q;// 由于单链表的每一个元素是单独分配的,所以要一个一个的进行释放while(*L ){q = (*L)—〉next;free(*L );//释放*L = q;}return 1;}/*将L重置为空表,即将链表中除头结点外的所有元素释放其存储空间,但是将头结点指针域置空,这和销毁有区别哦。
不改变L,所以不需要用指针。
*/int ClearList( LinkList L ){LinkList p,q;p = L—〉next;// p指向第一个结点while( p ) // 没到表尾则继续循环{q = p—>next;free( p );//释放空间p = q;}L—>next = NULL; // 头结点指针域为空,链表成了一个空表return 1;}// 若L为空表(根据头结点L—〉next来判断,为空则是空表),则返回1,// 否则返回0.int ListEmpty(LinkList L){if(L—>next ) // 非空return 0;elsereturn 1;}// 返回L中数据元素个数。
单链表应⽤实例及代码实现问题:使⽤带 head 头的单向链表实现 –英雄列表管理完成对英雄⼈物的增删改查操作。
⾸先准备⼀个hero类:1. class hero {2. private int num;//序号(排名)3. private String name;//名称4. private String nikname;//别名5. private hero next;//指向下⼀个6.7. public hero(int num, String name, String nikname) { ... } //构造器8.9. public int getNum() { ... }10. public void setNum(int num) { ... }11. public String getName() { ... }12. public void setName(String name) { ... }13. public String getNikname() { ... }14. public void setNikname(String nikname) { ... }15. public hero getNext() { ... }16. public void setNext(hero next) { ... }17.18. @Override19. public String toString() { ... } //为了显⽰⽅便显⽰重写tostring20. }1) 第⼀种⽅法:在添加英雄时,直接添加到链表的尾部(add())思路分析: 添加(创建) 1、先创建⼀个head头节点(①不存放具体数据,②作⽤就是表⽰单链表头next)private hero head = new hero(-1, "", ""); //先初始化⼀个头节点,头节点不能动,不存放具体数据 2、之后我们每添加⼀个节点,就直接加⼊到链表的最后 遍历 1、通过⼀个辅助变量遍历,帮助遍历整个链表2) 第⼆种⽅式在添加英雄时,根据排名将英雄插⼊到指定位置(如果有这个排名,则添加失败,并给出提⽰) 思路分析: 1、⾸先找到新添加的节点的位置,是通过辅助变量,通过遍历来搞定 2、新的节点.next=temp.next (temp为插⼊后的新节点的前⼀个节点) 3、将temp.next=新的节点3) 修改节点 思路分析: 1、先找到该节点,通过遍历 2、 = ; temp.nickname= newHero.nickname;4) 删除节点(delete()) 思路分析: 1、先找到需要删除的这个节点的前⼀个节点temp 2、 temp.next=temp.next.next 3、删除的节点,将不会有其他引⽤,会被GC掉单链表代码实现:1. public class singlelinkedlist {2. //先初始化⼀个头节点,头节点不能动,不存放具体数据3. private hero head = new hero(-1, "", "");4.5. //添加节点到单向链表6. /**7. * 思路:当不考虑标编号顺序时8. * 1、找到当前链表的最后节点9. * 2、将最后这个节点的next指向新的节点10. */11. public void add(hero h) {12. //因为head节点不能动,因此我们需要⼀个辅助变量temp13. hero temp = head;14. //遍历链表,找到最后⼀个节点15. while (true) {16. if (temp.getNext() == null) {17. break;19. //如果没有到最后,将temp后移20. temp = temp.getNext();21. }22. //当退出while循环时,temp就指向了链表的最后23. //将最后这个节点的next指向新的节点24. temp.setNext(h);25. }26.27. //第⼆种⽅式在添加英雄时,根据排名将英雄插⼊到指定位置28. //(如果有这个排名,则添加失败,并给出提⽰)29. public void addByOrder(hero h) {30. //因为头节点不能动,因此我们仍然通过⼀个辅助指针(变量)来帮助找到添加的位置31. //因为单链表,因为我们找的temp是位于添加位置的前⼀个节点,否则插⼊不了32. hero temp = head;33. boolean flag = false;// flag 标志添加的编号是否存在,默认为 false34. while (true) {35. if (temp.getNext() == null) {//说明 temp 已经在链表的最后36. break;37. } else if (temp.getNext().getNum() > h.getNum()) {//位置找到,就在 temp 的后⾯插⼊38. break;39. } else if (temp.getNext().getNum() == h.getNum()) {//说明希望添加的 heroNode 的编号已然存在40. flag = true;41. break;42. }43. temp = temp.getNext();//后移,遍历当前链表44. }45. if (flag) { //不能添加,说明编号存在46. System.out.println("添加的序号为" + h.getNum() + "的英雄序号已经存在,添加失败。
c语言中的链表用法在C语言中,链表是一种常见的数据结构,用于存储一系列数据项,每个数据项称为节点,每个节点包含两个部分:数据和指向下一个节点的指针。
以下是一个简单的链表实现示例:```cinclude <>include <>// 定义链表节点结构体typedef struct Node {int data;struct Node next;} Node;// 创建新节点Node createNode(int data) {Node newNode = (Node)malloc(sizeof(Node));newNode->data = data;newNode->next = NULL;return newNode;}// 在链表末尾添加节点void appendNode(Node head, int data) { Node newNode = createNode(data); if (head == NULL) {head = newNode;return;}Node current = head;while (current->next != NULL) {current = current->next;}current->next = newNode;}// 打印链表void printList(Node head) {while (head != NULL) {printf("%d ", head->data);head = head->next;}printf("\n");}int main() {Node head = NULL; // 链表头指针初始化为NULLappendNode(&head, 1); // 添加节点1appendNode(&head, 2); // 添加节点2appendNode(&head, 3); // 添加节点3printList(head); // 打印链表:1 2 3return 0;}```在这个示例中,我们定义了一个链表节点结构体,其中包含一个整型数据成员和一个指向下一个节点的指针成员。
C#数据结构之单链表(LinkList)实例详解本⽂实例讲述了C#数据结构之单链表(LinkList)实现⽅法。
分享给⼤家供⼤家参考,具体如下:这⾥我们来看下“单链表(LinkList)”。
在上⼀篇《》的最后,我们指出了:顺序表要求开辟⼀组连续的内存空间,⽽且插⼊/删除元素时,为了保证元素的顺序性,必须对后⾯的元素进⾏移动。
如果你的应⽤中需要频繁对元素进⾏插⼊/删除,那么开销会很⼤。
⽽链表结构正好相反,先来看下结构:每个元素⾄少具有⼆个属性:data和next。
data⽤来存放数据,⽽next⽤来指出它后⾯的元素是谁(有点“指针”的意思)。
链表中的元素,通常也称为节点Node,下⾯是泛型版本的Node.csnamespace 线性表{public class Node<T>{private T data;private Node<T> next;public Node(T val, Node<T> p){data = val;next = p;}public Node(Node<T> p){next = p;}public Node(T val){data = val;next = null;}public Node(){data = default(T);next = null;}public T Data{get { return data; }set { data = value; }}public Node<T> Next{get { return next; }set { next = value; }}}}链表在存储上并不要求所有元素按顺序存储,因为⽤节点的next就能找到下⼀个节点,这好象⼀根“⽤珠⼦串成的链⼦”,要找到其中的某⼀颗珠⼦,只要从第⼀颗节点(通常称为Head节点)开始,不断根据next指向找到下⼀个,直到找到需要的节点为⽌。