C++版数据结构单链表

合集下载

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

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

[转载整理]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语言数据结构之单链表

C语言数据结构之单链表

什么是链表?链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

其在物理地址上的存储示意图如下:链表的分类链表分为:单链表、循环单链表、双链表、循环双链表、静态链表。

单链表的概念1单链表的组成链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。

每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

2结点的分类结点可分为:头结点、开始结点(首元结点)、其他结点。

(1)头结点:其值域不包含任何信息。

不是必须的,根据实际情况建立。

(2)开始结点:开始结点也称做首元结点,代表链表中第一个存有数据的结点。

(3)其他结点:除了头结点与开始结点之外的结点。

3前驱与后继链表的相邻元素之间存在着序偶关系。

如用(a1,…,ai-1,ai,ai+1,…,an)表示一个链表,则表中ai-1领先于ai,ai领先于ai+1,称ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素。

当i=1,2,…,n-1时,ai有且仅有一个直接后继,当i=2,3,…,n 时,ai有且仅有一个直接前驱。

(ps:顺序表前驱和后继的概念也是如此)5头指针头指针head永远指向链表第一个节点的位置,头指针用于指明链表的位置,便于后期找到链表并使用表中的数据。

链表中有头结点时,头指针指向头结点;反之,若链表中没有头结点,则头指针指向开始结点。

链表完整示意图如下:6带头结点与不带头结点的单链表(1)带头结点的单链表:头指针head指向头结点。

头指针head始终不等于NULL,head->next等于NULL的时候链表为空。

(2)不带头结点的单链表:头结点head指向开始结点,当head等于NULL时链表为空。

单链表的操作示例1单链表结点的定义/* 数据元素类型 */typedef int ListType;/* 单链表结点定义 */typedef struct LNode{ListType data; //数据域struct LNode *next; //指针域,指向直接后继元素}LNode;2创建一个链表使用头插法创建一个链表:(5,2,0,13,14),代码如下3链表中查找某结点因为链表不支持随机访问,即链表的存取方式是顺序存取的(注意“存储”与“存取”是两个不一样的概念),所以要查找某结点,必须通过遍历的方式查找。

单链表(C语言实现)

单链表(C语言实现)

单链表(C语⾔实现)链表结构:SList.h//--------------------------------------------------------------------------/***功能:应⽤C语⾔实现单链表的各项操作****** 1:建⽴节点** 2:打印单链表** 3:尾插** 4:尾删** 5:头插** 6:头删** 7:清空整个链表** 8:获取链表长度** 9:查找数据** 10:在某位置后插⼊数据** 11:删除某位置的数据** 12:删除⼀个⽆头单链表的⾮尾节点** 13:在⽆头单链表的⼀个⾮头节点前插⼊⼀个节点** 14:查找中间节点** 15:查找倒数第k个节点(要求只能遍历⼀次)** 16:倒着打印单链表** 17:逆置单链表** 18:合并两个有序链表(合并后依然有序)** 19:冒泡排序****** By :Lynn-Zhang***///---------------------------------------------------------------------------#pragma oncetypedef int DataType;typedef struct SListNode{DataType data; // 数据struct SListNode* next; //指向下⼀个节点的指针}SListNode;// 如果要修改链表就必须加引⽤SListNode* _BuyNode(DataType x); //建⽴节点void PrintSlist(SListNode* pHead); //打印单链表void PushBack(SListNode* & pHead, DataType x); //尾插(这⾥⽤了引⽤,指明是list的别名,调⽤时传参,不⽤传地址)(引⽤在.c⽂件中不可⽤) //void PushBack(SListNode** pHead, DataType x); // 这⾥的第⼀个参数指向链表第⼀个节点的指针的地址(调⽤时传参,传的是地址)void PopBack(SListNode* & pHead); //尾删void PushFront(SListNode* & pHead, DataType x); //头插void PopFront(SListNode* & pHead); //头删void DestoryList(SListNode*& pHead); //清空整个链表int GetSize(SListNode* pHead); //获取链表长度SListNode* Find(SListNode* pHead, DataType x); //查找数据void Insert(SListNode* pos, DataType x); //在某位置后插⼊数据void Erase(SListNode*& pHead, SListNode* pos); //删除某位置的数据void DelNonTailNode(SListNode* pos); //删除⼀个⽆头单链表的⾮尾节点void InsertFrontNode(SListNode* pos, DataType x); // 在⽆头单链表的⼀个⾮头节点前插⼊⼀个节点SListNode* FindMidNode(SListNode* pHead); //查找中间节点SListNode* FindKNode(SListNode* pHead, int k); //查找倒数第k个节点(要求只能遍历⼀次)void PrintTailToHead(SListNode* pHead); //倒着打印单链表(递归)//SListNode* Reverse_(SListNode* pHead); //逆置单链表(需要接收返回值),原链表会被改void Reverse(SListNode*& pHead); // 将原链表逆置SListNode* Merge(SListNode* pHead1, SListNode* pHead2); //合并两个有序链表(合并后依然有序)(递归)void Sort(SListNode* pHead); //冒泡排序SList.cpp#include"SList.h"#include <stdio.h>#include<assert.h>#include <malloc.h>SListNode* _BuyNode(DataType x) //建⽴节点{SListNode* tmp = (SListNode*)malloc(sizeof(SListNode)); tmp->data = x;tmp->next = NULL;return tmp;}void PrintSlist(SListNode* pHead) // 打印单链表{SListNode* cur = pHead;while (cur){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");}//void PushBack(SListNode** ppHead, DataType x) //尾插//{// assert(ppHead);//// 1.空//// 2.不为空// if(*ppHead == NULL)// {// *ppHead = _BuyNode(x);// }// else// {//// 找尾// SListNode* tail = *ppHead;// while(tail->next != NULL)// {// tail = tail->next;// }//// tail->next = _BuyNode(x);// }//}void PushBack(SListNode* & pHead, DataType x) //尾插{// 1.空// 2.不为空if (pHead == NULL){pHead = _BuyNode(x);}else{// 找尾SListNode* tail = pHead;while (tail->next != NULL){tail = tail->next;}tail->next = _BuyNode(x);}}void PopBack(SListNode* & pHead) // 尾删{//// 1.空// 2.⼀个节点// 3.多个节点//if (pHead == NULL){return;}else if (pHead->next == NULL){free(pHead);pHead = NULL;}else{SListNode* tail = pHead;SListNode* prev = NULL;while (tail->next){prev = tail;tail = tail->next;}free(tail);prev->next = NULL;}}void PushFront(SListNode* & pHead, DataType x) //头插{// 1.空// 2.不空if (pHead == NULL){pHead = _BuyNode(x);}else{SListNode* tmp = _BuyNode(x);tmp->next = pHead;pHead = tmp;}}void PopFront(SListNode*& pHead) //头删{//// 1.空// 2.⼀个节点// 3.⼀个以上的节点//if (pHead == NULL){return;}else if (pHead->next == NULL){free(pHead);pHead = NULL;}else{SListNode* tmp = pHead;pHead = pHead->next;free(tmp);}}void DestoryList(SListNode*& pHead) //清空整个链表{SListNode* cur = pHead;while (cur){SListNode* tmp = cur;cur = cur->next;free(tmp);}pHead = NULL;}int GetSize(SListNode* pHead) //获取链表长度{assert(pHead);SListNode* cur = pHead;int count = 0;while (cur){count++;cur = cur->next;}return count;}SListNode* Find(SListNode* pHead, DataType x) //查找节点{SListNode* cur = pHead;while (cur){if (cur->data == x)return cur;}cur = cur->next;}return NULL;}void Insert(SListNode* pos, DataType x) // 某位置后插⼊节点{assert(pos);SListNode* tmp = _BuyNode(x);tmp->next = pos->next;pos->next = tmp;}void Erase(SListNode*& pHead, SListNode* pos) //删除某位置的节点{assert(pos);assert(pHead);//pos为头结点if (pHead == pos){pHead = pHead->next;free(pos);return;}////SListNode* prev = pHead;while (prev){if (prev->next == pos){prev->next = pos->next;free(pos);break;}prev = prev->next;}}void DelNonTailNode(SListNode* pos) //// 删除⼀个⽆头单链表的⾮尾节点{assert(pos);assert(pos->next);SListNode* del = pos->next;SListNode* dnext = del->next;pos->data = del->data;pos->next = dnext;free(del);}void InsertFrontNode(SListNode* pos, DataType x) // 在⽆头单链表的⼀个⾮头节点前插⼊⼀个节点{assert(pos);SListNode* tmp = _BuyNode(pos->data);tmp->next = pos->next;pos->next = tmp;pos->data = x;}void Sort(SListNode* pHead) //冒泡排序{assert(pHead);int size = GetSize(pHead);for (int i = 0; i < size - 1; i++){SListNode* left = pHead;SListNode* right = pHead->next;for (int j = 0; j < size - i - 1; j++){if (left->data>right->data){int tmp = left->data;left->data = right->data;right->data = tmp;}right = right->next;left = left->next;}}SListNode* FindMidNode(SListNode* pHead) //查找中间节点{SListNode* fast = pHead;SListNode* slow = pHead;while (fast&&fast->next){slow = slow->next;fast = fast->next->next;}return slow;}SListNode* FindKNode(SListNode* pHead, int k) //查找倒数第k个节点{SListNode* fast = pHead;SListNode* slow = pHead;while (fast && k--){fast = fast->next;}if (k > 0){return NULL;}while (fast){slow = slow->next;fast = fast->next;}return slow;}void PrintTailToHead(SListNode* pHead) //倒着打印单链表(递归){if (pHead){PrintTailToHead(pHead->next);printf("%d ", pHead->data);}}//SListNode* Reverse_(SListNode* pHead) //逆置单链表(需要接收返回值)原链表会被改//{// SListNode* cur = pHead;// SListNode* newHead = NULL;// while (cur)// {// SListNode* tmp = cur;// cur = cur->next;// tmp->next = newHead;// newHead = tmp;// }// return newHead;//}void Reverse(SListNode*& pHead) //逆置单链表(⽆需返回值){SListNode* cur = pHead;SListNode* newHead = NULL;while (cur){SListNode* tmp = cur;cur = cur->next;tmp->next = newHead;newHead = tmp;}pHead = newHead;//return newHead;}SListNode* Merge(SListNode* pHead1, SListNode* pHead2) //合并两个有序链表(合并后依然有序)递归{if (pHead1 == NULL)return pHead2;else if (pHead2 == NULL)return pHead1;SListNode* pMergedHead = NULL;if (pHead1->data < pHead2->data){pMergedHead = pHead1;pMergedHead->next = Merge(pHead1->next, pHead2); }else{pMergedHead = pHead2;pMergedHead->next = Merge(pHead1, pHead2->next); }return pMergedHead;}Test.cpp#include "SList.h"#include<stdlib.h>//测试⽤例void Test1(){// 尾插打印尾删头插头删清空链表SListNode* list = NULL;PushBack(list, 1);PushBack(list, 2);PushBack(list, 3);PushBack(list, 4);PrintSlist(list);PopBack(list);PrintSlist(list);PushFront(list,0);PrintSlist(list);PopFront(list);PrintSlist(list);DestoryList(list);PrintSlist(list);}void Test2(){// 查找节点在某位置插⼊节点删除某位置节点SListNode* list = NULL;PushBack(list, 1);PushBack(list, 2);PushBack(list, 3);PushBack(list, 4);PrintSlist(list);SListNode* pos = Find(list, 2);Insert(pos, 0);PrintSlist(list);Erase(list, Find(list, 0));PrintSlist(list);}void Test3(){SListNode* list = NULL;PushBack(list, 1);PushBack(list, 2);PushBack(list, 3);PushBack(list, 4);PushBack(list, 5);PushBack(list, 6);PrintSlist(list);// 删除⼀个⽆头单链表的⾮尾节点/*SListNode* pos = Find(list, 2);DelNonTailNode(pos);PrintSlist(list);*/// 在⽆头单链表的⼀个⾮头节点前插⼊⼀个节点/*SListNode* pos = Find(list, 2);InsertFrontNode(pos, 0);PrintSlist(list);*///查找中间节点//PrintSlist(FindMidNode(list));//查找倒数第k个节点//SListNode* ret = FindKNode(list, 2);//PrintSlist(ret);//倒着打印单链表(递归)//PrintTailToHead(list);//逆置单链表//SListNode* ret = Reverse(list);//PrintSlist(ret);//PrintSlist(Reverse_(list));//PrintSlist(list);}void Test4(){ //合并两个有序链表(合并后依然有序) SListNode* list = NULL;PushBack(list, 4);PushBack(list, 2);PushBack(list, 1);PushBack(list, 4);PrintSlist(list);Sort(list);PrintSlist(list);/*SListNode* list1 = NULL;PushBack(list1, 2);PushBack(list1, 3);PushBack(list1, 3);PushBack(list1, 0);PrintSlist(list);Sort(list1);PrintSlist(list1);SListNode* ret = Merge(list, list1);PrintSlist(ret);PrintSlist(list);PrintSlist(list1);*/}int main(){//Test1();//Test2();//Test3();Test4();system("pause");return0;}。

写出单链表存储结构的 c 语言描述

写出单链表存储结构的 c 语言描述

写出单链表存储结构的 c 语言描述一、单链表的概述单链表是一种常见的数据结构,它由若干个节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。

单链表的特点是插入和删除操作效率高,但查找操作效率较低。

二、单链表的存储结构单链表的存储结构采用动态分配内存的方式,每个节点都是一个独立的内存区域,通过指针将它们连接在一起。

下面是单链表存储结构的 c 语言描述:```typedef struct Node{int data; // 数据域struct Node *next; // 指针域} ListNode, *LinkedList;```上面代码中,ListNode 表示节点类型,LinkedList 表示链表类型。

其中 data 是数据域,next 是指针域,用于存放下一个节点的地址。

三、单链表的基本操作1. 初始化操作初始化操作用于创建一个空链表。

```void InitList(LinkedList *L){*L = (ListNode*)malloc(sizeof(ListNode)); // 创建头结点(*L)->next = NULL; // 头结点指针域为空}```2. 插入操作插入操作用于在链表中插入新节点。

```int Insert(LinkedList L, int i, int x)int j = 0;ListNode *p = L;while (p && j < i - 1) // 找到第 i-1 个节点{p = p->next;j++;}if (!p || j > i - 1) // 判断 i 的范围是否合法{return 0;}ListNode *s = (ListNode*)malloc(sizeof(ListNode)); // 创建新节点s->data = x; // 赋值数据域s->next = p->next; // 新节点指向下一个节点p->next = s; // 前一个节点指向新节点 return 1;```3. 删除操作删除操作用于删除链表中的某个节点。

单链表数据结构

单链表数据结构

插入
if (p != NULL && j == i-1) { // 找到第i个结点
s = (LinkList) malloc ( sizeof (LNode)); // 生成新结点
s->data = e;
// 数据域赋值
s->next = p->next; //新结点指针指向后一结点
p->next = s; return OK;
6、销毁
4.6 销毁操作
while(L) { p = L->next; free(L); L=p;
// p指向第一结点(头节点为“哑结点”) // 释放首结点 // L指向p
}
// 销毁完成后,L为空(NULL)
算法的时间复杂度为:O(ListLength(L))
判空 求表长
4.7 其它操作
if(L->next==NULL) return TRUE; // 空
5、清空
4.5 清空操作
while (L->next) { p = L->next; L->next = p->next; free(p);
// p指向当前结点 // 头结点指向当前结点的后结点 // 释放当前结点内存
}
// 清空完成后,仍保留头结点L
算法的时间复杂度为:O(ListLength(L))
点。
5.1.2 逆序建立单链表
①建立一个带头结点的空单链表;
②输入数据元素ai,建立新结点p, 并把p插入在头结点之后成为第一个 结点。
③重复执行②步,直到完成单链表的 建立。
a1
a2 a1
创建出来的链表 点顺序与插入操作
顺序相反。

单链表的基本操作c语言

单链表的基本操作c语言

单链表的基本操作(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. 插入节点在单链表中插入一个新的节点需要进行以下步骤:•创建一个新的节点。

数据结构单链表实验报告

数据结构单链表实验报告

数据结构单链表实验报告一、实验目的1、深入理解单链表的数据结构及其基本操作。

2、掌握单链表的创建、插入、删除、查找等操作的实现方法。

3、通过实际编程,提高对数据结构和算法的理解和应用能力。

二、实验环境1、操作系统:Windows 102、编程语言:C 语言3、开发工具:Visual Studio 2019三、实验原理单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据域和指针域。

指针域用于指向下一个节点,从而形成链表的链式结构。

单链表的基本操作包括:1、创建链表:通过动态分配内存创建链表的头节点,并初始化链表为空。

2、插入节点:可以在链表的头部、尾部或指定位置插入新的节点。

3、删除节点:根据给定的条件删除链表中的节点。

4、查找节点:在链表中查找满足特定条件的节点。

四、实验内容(一)单链表的创建```cinclude <stdioh>include <stdlibh>//定义链表节点结构体typedef struct Node {int data;struct Node next;} Node;//创建单链表Node createList(){Node head =(Node)malloc(sizeof(Node));if (head == NULL) {printf("内存分配失败!\n");return NULL;}head>data = 0;head>next = NULL;return head;}int main(){Node list = createList();//后续操作return 0;}```在创建单链表时,首先为头节点分配内存空间。

若内存分配失败,则提示错误信息并返回`NULL`。

成功分配内存后,初始化头节点的数据域和指针域。

(二)单链表的插入操作插入操作分为三种情况:头部插入、尾部插入和指定位置插入。

1、头部插入```cvoid insertAtHead(Node head, int data) {Node newNode =(Node)malloc(sizeof(Node));if (newNode == NULL) {printf("内存分配失败!\n");return;}newNode>data = data;newNode>next = head>next;head>next = newNode;}```头部插入时,创建新节点,将新节点的数据域赋值,并将其指针域指向原头节点的下一个节点,然后更新头节点的指针域指向新节点。

数据结构c语言版创建单链表的代码

数据结构c语言版创建单链表的代码

数据结构c语言版创建单链表的代码单链表作为常用的线性结构之一,常常用于解决以链式方式存储数据的问题。

创建单链表需要掌握一些基础的数据结构知识以及对C语言的熟练运用。

接下来,本文将分步骤地阐述数据结构C语言版创建单链表的代码。

第一步,定义单链表结构体并定义节点类型。

在C语言中,我们可以通过结构体的方式定义单链表,其中结构体中包含两个成员变量,分别为存储数据的data和指向下一个节点的指针next。

对于节点类型,我们可以使用typedef对节点类型进行定义,例如:```struct ListNode {int data;struct ListNode *next;};typedef struct ListNode ListNode;```在以上代码中,我们首先定义了一个结构体ListNode作为单链表的元素类型,其中包含存储数据的data和指向下一个元素的指针next。

接着我们使用typedef将结构体ListNode定义为仿函数ListNode,从而使其更加方便使用。

第二步,初始化单链表。

在创建单链表之前,我们需要先将单链表的头指针初始化为NULL,表示当前链表为空。

具体代码如下:```ListNode *createLinkedList() {ListNode *head = NULL;return head;}```以上代码中,函数createLinkedList用于创建并初始化单链表,其中head表示单链表头指针,我们将其初始化为NULL。

第三步,向单链表中添加元素。

在单链表中添加元素需要借助于指针的指向关系。

具体来说,我们需要先创建新的节点,将其数据添加到节点中,然后将新节点的next指针指向之前的头节点,最后将头指针指向新节点。

具体过程如下:```ListNode *addListNode(ListNode **head, int val) {ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = val;newNode->next = *head;*head = newNode;return *head;}```在以上代码中,函数addListNode接收一个指向头指针的指针head,以及需要添加的元素值val。

数据结构C语言版 线性表的单链表存储结构表示和实现

数据结构C语言版 线性表的单链表存储结构表示和实现

#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中数据元素个数。

c语言单链表尾插法

c语言单链表尾插法

C语言单链表尾插法1. 简介单链表是一种常用的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。

单链表尾插法是一种在链表尾部插入新节点的方法,通过将新节点插入到链表尾部,可以方便地实现链表的动态扩展和插入操作。

本文将详细介绍C语言中单链表尾插法的实现方法,包括链表结构的定义、节点的插入操作、遍历和释放链表等。

2. 链表结构定义在C语言中,我们可以通过结构体来定义链表的节点。

每个节点包含两个部分:数据域和指针域。

typedef struct Node {int data; // 数据域struct Node* next; // 指针域,指向下一个节点} Node;在上述代码中,我们定义了一个名为Node的结构体,其中data表示节点的数据,next表示指向下一个节点的指针。

通过typedef关键字,我们将struct Node重命名为Node,方便后续使用。

3. 节点的插入操作3.1 创建新节点在进行节点的插入操作之前,我们需要先创建一个新的节点。

可以通过动态内存分配函数malloc来分配内存,并使用free函数释放内存。

Node* createNode(int data) {Node* newNode = (Node*)malloc(sizeof(Node));if (newNode == NULL) {printf("内存分配失败\n");exit(1);}newNode->data = data;newNode->next = NULL;return newNode;}上述代码中,我们定义了一个名为createNode的函数,该函数接受一个整数参数data,用于初始化新节点的数据域。

首先使用malloc函数分配内存,并将返回的指针强制转换为Node*类型。

然后,我们检查内存分配是否成功,如果失败,则打印错误信息并调用exit函数退出程序。

接着,我们将新节点的数据域设置为传入的data值,指针域设置为NULL,最后返回新节点的指针。

C#数据结构之单链表(LinkList)实例详解

C#数据结构之单链表(LinkList)实例详解

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指向找到下⼀个,直到找到需要的节点为⽌。

数据结构c语言版课后习题答案

数据结构c语言版课后习题答案

数据结构c语言版课后习题答案数据结构是计算机科学中的一个重要概念,它涉及到组织、管理和存储数据的方式,以便可以有效地访问和修改数据。

C语言是一种广泛使用的编程语言,它提供了丰富的数据结构实现方式。

对于学习数据结构的C语言版课程,课后习题是巩固理论知识和提高实践能力的重要手段。

数据结构C语言版课后习题答案1. 单链表的实现在C语言中,单链表是一种常见的线性数据结构。

它由一系列节点组成,每个节点包含数据部分和指向下一个节点的指针。

实现单链表的基本操作通常包括创建链表、插入节点、删除节点、遍历链表等。

答案:- 创建链表:定义一个链表结构体,然后使用动态内存分配为每个节点分配内存。

- 插入节点:根据插入位置,调整前后节点的指针,并将新节点插入到链表中。

- 删除节点:找到要删除的节点,调整其前后节点的指针,然后释放该节点的内存。

- 遍历链表:从头节点开始,使用指针遍历链表,直到达到链表尾部。

2. 二叉树的遍历二叉树是一种特殊的树形数据结构,其中每个节点最多有两个子节点。

二叉树的遍历是数据结构中的一个重要概念,常见的遍历方式有前序遍历、中序遍历、后序遍历和层序遍历。

答案:- 前序遍历:先访问根节点,然后递归遍历左子树,最后递归遍历右子树。

- 中序遍历:先递归遍历左子树,然后访问根节点,最后递归遍历右子树。

- 后序遍历:先递归遍历左子树,然后递归遍历右子树,最后访问根节点。

- 层序遍历:使用队列,按照从上到下,从左到右的顺序访问每个节点。

3. 哈希表的实现哈希表是一种通过哈希函数将键映射到表中一个位置来访问记录的数据结构。

它提供了快速的数据访问能力,但需要处理哈希冲突。

答案:- 哈希函数:设计一个哈希函数,将键映射到哈希表的索引。

- 哈希冲突:使用链地址法、开放地址法或双重哈希法等解决冲突。

- 插入操作:计算键的哈希值,将其插入到对应的哈希桶中。

- 删除操作:找到键对应的哈希桶,删除相应的键值对。

4. 图的表示和遍历图是一种复杂的非线性数据结构,由顶点(节点)和边组成。

数据结构--数组、单链表和双链表介绍以及双向链表

数据结构--数组、单链表和双链表介绍以及双向链表

数据结构--数组、单链表和双链表介绍以及双向链表数组:数组有上界和下界,数组的元素在上下界内是连续的。

数组的特点是:数据是连续的;随机访问速度快。

数组中稍微复杂⼀点的是多维数组和动态数组。

对于C语⾔⽽⾔,多维数组本质上也是通过⼀维数组实现的。

⾄于动态数组,是指数组的容量能动态增长的数组;对于C语⾔⽽⾔,若要提供动态数组,需要⼿动实现;⽽对于C++⽽⾔,STL提供了Vector。

单向链表:单向链表(单链表)是链表的⼀种,它由节点组成,每个节点都包含下⼀个节点的指针。

表头为空,表头的后继节点是"节点10"(数据为10的节点),"节点10"的后继节点是"节点20"(数据为10的节点),"节点20"的后继节点是"节点30"(数据为20的节点),"节点30"的后继节点是"节点40"(数据为10的节点),......删除"节点30"删除之前:"节点20" 的后继节点为"节点30",⽽"节点30" 的后继节点为"节点40"。

删除之后:"节点20" 的后继节点为"节点40"。

在"节点10"与"节点20"之间添加"节点15"添加之前:"节点10" 的后继节点为"节点20"。

添加之后:"节点10" 的后继节点为"节点15",⽽"节点15" 的后继节点为"节点20"。

单链表的特点是:节点的链接⽅向是单向的;相对于数组来说,单链表的的随机访问速度较慢,但是单链表删除/添加数据的效率很⾼。

单链表存储结构c语言

单链表存储结构c语言

单链表存储结构c语言单链表是一种常见的数据结构,它由节点组成,每个节点包含数据和指向下一个节点的指针。

在C语言中,可以使用结构体来表示单链表的节点,然后通过指针来连接这些节点。

首先,我们需要定义单链表节点的结构体。

这个结构体包含两部分,数据部分和指针部分。

数据部分可以是任何我们想要存储的数据类型,指针部分用来指向下一个节点。

c.struct Node {。

int data; // 以整数为例,实际可以是任何数据类型。

struct Node next; // 指向下一个节点的指针。

};接下来,我们可以编写一些操作单链表的函数,比如创建节点、插入节点、删除节点等。

以下是一些常用的单链表操作函数的示例:1. 创建节点函数。

c.struct Node createNode(int data) {。

struct Node newNode = (structNode)malloc(sizeof(struct Node));newNode->data = data;newNode->next = NULL;return newNode;}。

2. 插入节点函数。

c.void insertNode(struct Node head, int data) {。

struct Node newNode = createNode(data);struct Node temp = head;while (temp->next != NULL) {。

temp = temp->next;}。

temp->next = newNode;}。

3. 删除节点函数。

c.void deleteNode(struct Node head, int data) {。

struct Node temp = head;struct Node prev = NULL;while (temp != NULL && temp->data != data) {。

数据结构c语言版上机报告单链表

数据结构c语言版上机报告单链表

数据结构C语言版上机报告:单链表序在数据结构课程中,单链表是一个重要的概念,也是C语言中常用的数据结构之一。

本次报告将深入探讨单链表的基本概念、操作方法以及应用场景,帮助读者更深入地理解和掌握这一数据结构。

一、概述1.1 单链表的定义单链表是一种线性表,它由一系列节点组成,每个节点包含两部分:数据域和指针域。

数据域用于存储数据元素,指针域用于指向下一个节点,通过指针将这些节点串联在一起,形成一个链表结构。

1.2 单链表的特点单链表具有以下特点:(1)动态性:单链表的长度可以动态地增加或减少,不需要预先分配固定大小的空间。

(2)插入和删除操作高效:在单链表中进行插入和删除操作时,只需要修改指针的指向,时间复杂度为O(1)。

(3)随机访问效率低:由于单链表采用链式存储结构,无法通过下标直接访问元素,需要从头节点开始依次遍历,时间复杂度为O(n)。

1.3 单链表的基本操作单链表的基本操作包括:创建、插入、删除、查找等。

这些操作是使用单链表时常常会涉及到的,下面将逐一介绍这些操作的具体实现方法和应用场景。

二、创建2.1 头插法和尾插法在C语言中,可以通过头插法和尾插法来创建单链表。

头插法是将新节点插入到链表的头部,尾插法是将新节点插入到链表的尾部,这两种方法各有优缺点,可以根据具体应用场景来选择。

2.2 应用场景头插法适合于链表的逆序建立,尾插法适合于链表的顺序建立。

三、插入3.1 在指定位置插入节点在单链表中,插入节点需要考虑两种情况:在链表头部插入和在链表中间插入。

通过对指针的操作,可以实现在指定位置插入节点的功能。

3.2 应用场景在实际应用中,经常会有需要在指定位置插入节点的情况,比如排序操作、合并两个有序链表等。

四、删除4.1 删除指定节点在单链表中,删除节点同样需要考虑两种情况:删除头节点和删除中间节点。

通过对指针的操作,可以实现删除指定节点的功能。

4.2 应用场景在实际应用中,经常会有需要删除指定节点的情况,比如删除链表中特定数值的节点等。

数据结构c++顺序表、单链表的基本操作,查找、排序代码

数据结构c++顺序表、单链表的基本操作,查找、排序代码

实验1:顺序表的基本操作实验2:单链表的基本操作实验3:查找实验4:排序实验1代码及结果:#include <iostream>using namespace std;template <class T>class sq_LList{private:int mm;int nn;T *v;public:sq_LList(){mm=0;nn=0;return;}sq_LList(int);void prt_sq_LList();int flag_sq_LList();void ins_sq_LList(int,T);void del_sq_LList(int);};//建立空顺序表template <class T>sq_LList<T>::sq_LList(int m){mm=m;v=new T[mm];nn=0;return;}//顺序输出顺序表中的元素与顺序表长度template <class T>void sq_LList<T>::prt_sq_LList(){int i;cout<<"nn="<<nn<<endl;for(i=0;i<nn;i++)cout<<v[i]<<endl; return;}//检测顺序表的状态template <class T>int sq_LList<T>::flag_sq_LList(){if(nn=mn)return(-1);if(nn=0)return(0);return (1);}//在表的指定元素前插入新元素template<class T>void sq_LList<T>::ins_sq_LList(int i,T b){int k;if(nn==mm){cout<<"overflow"<<endl;return;}if(i>nn)i=nn+1;if(i<1)i=1;for(k=nn;k>=i;k--)v[k]=v[k-1];v[i-1]=b;nn=nn+1;return ;}//在顺序表中删除指定元素template<class T>void sq_LList<T>::del_sq_LList(int i){int k;if(nn==0){cout<<"underflow!"<<endl;return;}for(k=i;k<nn;k++)v[k-1]=v[k];nn=nn-1;return ;}int main(){sq_LList<double>s1(100);cout<<"第一次输出顺序表对象s1:"<<endl; s1.prt_sq_LList();s1.ins_sq_LList(0,1.5);s1.ins_sq_LList(1,2.5);s1.ins_sq_LList(4,3.5);cout<<"第二次输出顺序表对象s1:"<<endl; s1.prt_sq_LList();s1.del_sq_LList(0);s1.del_sq_LList(2);cout<<"第三次输出顺序表对象s1:"<<endl; s1.prt_sq_LList();return 0;}运行及结果:实验2代码#include<iostream>#include<iomanip>using namespace std;struct node{float data;node *next;};node *create(){ //建立单链表node *head,*p,*s;head=new node;p=head;p->data=0;p->next=0; //表头创建完成float newnum=0;cin>>newnum;if(newnum<0){cout<<"未输入数据...\n";//输入负数则结束system("pause");}while(newnum>=0 ){ //??如何用字符型作为结束标志s=new node; //创建表中数据s->data=newnum;p->next=s;p=s;cin>>newnum;}p->next=NULL; //最后元素指针return(head); //返回空表头}//插入一个结点x,将成为第i个节点void insertnode(node *head,int i,float x){node *s,*p;int j;s=new node;s->data=x;p=head;j=1; //查找第i个结点,由p指向while(p!=NULL && j<i){j++;p=p->next;}s->next=p->next;p->next=s;}//删除结点xvoid deletenode(node *head,float x){node *p,*s;if(head->next==NULL)cout<<"这是空链表,不能执行删除操作\n"; else{s=head;p=head->next;while(p!=NULL && p->data!=x)if(p->data!=x){s=p;p=p->next;}if(p!=NULL){s->next=p->next;delete(p);}else cout<<"未找到!\n";}}//存取链表某节点Kvoid read(node*head,int k){while(head->next!=0&&k>0){head=head->next;k--;}cout<<"该处数据为"<<head->data<<".\n\n"; }int main( ) {node *linktable=0;int choice=1;cout<<"1.创建链表\n";cout<<"2.显示信息\n";cout<<"3.删除信息\n";cout<<"4.查找信息\n";cout<<"5.插入信息\n";cout<<"6.读取信息\n";cout<<"0.退出程序\n";cout<<"请输入您的选择:";cin>>choice;while(1){switch (choice){case 0: exit(0);case 1:{cout<<"输入正数数据,并以负数作为结束标记\n";linktable=create();break;}case 2:{cout<<"链表长度为"<<length(linktable)<<",详细信息:\n";printlist(linktable);break;}case 3:{cout<<"要删除的数据为?\n";float del;cin>>del;deletenode(linktable,del);break;}case 4:{if(linktable->next==0)cout<<"链表为空,不能查找\n";else{cout<<"要查找数据为?";float search;cin>>search;find(linktable,search);} break;}case 5:{cout<<"存储数据为?";int des;float it;cin>>it;cout<<"想让该数据存储为第几个节点?";cin>>des;if((des>(length(linktable)+1)||des<1))cout<<"输入错误\n";elseinsertnode(linktable,des,it);break;}case 6:{cout<<"想读取第几个节点?";int c;cin>>c;if(c<1||c>length(linktable))cout<<"位置不合法\n";elseread(linktable,c);break;}default :cout<<"输入错误!\n";}system("pause");system("cls");cout<<"当前信息:\n";printlist(linktable);cout<<"\n1.创建链表\n";cout<<"2.显示信息\n";cout<<"3.删除信息\n";cout<<"4.查找信息\n";cout<<"5.插入信息\n";cout<<"6.读取信息\n";cout<<"0.退出程序\n";cout<<"继续选择:\n";cin>>choice;}return 0;}实验三查找实验名称:实验3 查找实验目的:掌握顺序表和有序表的查找方法及算法实现;掌握二叉排序树和哈希表的构造和查找方法。

数据结构c语言版单链表心得

数据结构c语言版单链表心得

数据结构c语言版单链表心得介绍在计算机科学中,数据结构是组织和存储数据的方式,目的是使数据可以高效地操作和访问。

而在C语言中,单链表是一种常见的数据结构,它由节点组成,每个节点包含数据和指向下一个节点的指针。

在本篇文章中,我将分享我对C语言版单链表的体会和心得。

什么是单链表单链表是一种线性数据结构,它由一系列节点组成。

每个节点包含两个部分:数据和指针。

数据部分用来存储具体的数据,而指针部分用来指向下一个节点。

通过使用指针,可以将各个节点连接起来,形成一个链表的结构。

单链表的设计与实现在C语言中,我们可以使用结构体来定义链表的节点类型。

每个节点包含一个数据域和一个指向下一个节点的指针域。

以下是单链表节点的定义:typedef struct Node {int data;struct Node* next;} Node;通过定义一个指向链表头节点的指针,我们可以操作链表。

以下是单链表的实现:#include <stdio.h>#include <stdlib.h>typedef struct Node {int data;struct Node* next;} Node;void insert(Node** head, int data) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = data;newNode->next = *head;*head = newNode;}void printList(Node* head) {Node* curr = head;while (curr != NULL) {printf("%d ", curr->data);curr = curr->next;}}int main() {Node* head = NULL;insert(&head, 1);insert(&head, 2);insert(&head, 3);insert(&head, 4);printList(head);return 0;}单链表的插入操作向单链表中插入节点是一种常见的操作。

数据结构(C语言)用单链表存储一元多项式,并实现两个多项式的相加运算

数据结构(C语言)用单链表存储一元多项式,并实现两个多项式的相加运算

#include<stdio.h>#include<stdlib.h>#include<malloc.h>typedef int ElemType;/*单项链表的声明*/typedef struct PolynNode{int coef; // 系数int expn; // 指数struct PolynNode *next;}PolynNode,*PolynList;/*正位序(插在表尾)输入n个元素的值,建立带表头结构的单链线性表*/ /*指数系数一对一对输入*/void CreatePolyn(PolynList &L,int n){int i;PolynList p,q;L=(PolynList)malloc(sizeof(PolynNode)); // 生成头结点L->next=NULL;q=L;printf("成对输入%d个数据\n",n);for(i=1;i<=n;i++){p=(PolynList)malloc(sizeof(PolynNode));scanf("%d%d",&p->coef,&p->expn); //指数和系数成对输入q->next=p;q=q->next;}p->next=NULL;}// 初始条件:单链表L已存在// 操作结果: 依次对L的每个数据元素调用函数vi()。

一旦vi()失败,则操作失败void PolynTraverse(PolynList L,void(*vi)(ElemType, ElemType)){PolynList p=L->next;while(p){vi(p->coef, p->expn);if(p->next){printf(" + "); //“+”号的输出,最后一项后面没有“+”}p=p->next;}printf("\n");}/*ListTraverse()调用的函数(类型要一致)*/void visit(ElemType c, ElemType e){if(c != 0){printf("%dX^%d",c,e); //格式化输出多项式每一项 }}/* 多项式相加,原理:归并 *//* 参数:两个已经存在的多项式 *//* 返回值:归并后新的多项式的头结点 */PolynList MergeList(PolynList La, PolynList Lb){PolynList pa, pb, pc, Lc;pa = La->next;pb = Lb->next;Lc = pc = La; // 用La的头结点作为Lc的头结点while(pa&&pb){if(pa->expn < pb->expn){pc->next = pa; //如果指数不相等,pc指针连上指数小的结点,pc = pa;pa = pa->next; //指向该结点的指针后移}else if(pa ->expn > pb->expn ){pc->next = pb; //pc指针连上指数小的结点,pc = pb;pb = pb->next; //指向该结点的指针后移}else//(pa ->expn = pb->expn ){pa->coef = pa->coef + pb->coef; //指数相等时,系数相加pc->next = pa;pc = pa;pa = pa->next; //两指针都往后移pb = pb->next;}}pc->next = pa ? pa:pb; // 插入剩余段return Lc;}void main(){PolynList ha,hb,hc;printf("非递减输入多项式ha, ");CreatePolyn(ha,5); // 正位序输入n个元素的值 printf("非递减输入多项式hb, ");CreatePolyn(hb,5); // 正位序输入n个元素的值 printf("多项式ha :");PolynTraverse(ha, visit);printf("\n");printf("多项式hb :");PolynTraverse(hb, visit);printf("\n");hc = MergeList(ha,hb);PolynTraverse(hc, visit);}。

c语言单链表基本操作

c语言单链表基本操作
prevNode->next = currentNode->next; } free(currentNode); // 释放内存 } } ```
c语言单链表基本操作
5. 查找节点:
```c struct Node* searchNode(struct Node* head, int data) {
c语言单链表基本操作
4. 删除节点:
```c void deleteNode(struct Node** head, int data) {
struct Node* currentNode = *head; struct Node* prevNode = NULL;
// 遍历链表,找到要删除的节点 while (currentNode != NULL && currentNode->data != data) {
c语言单链表基本操作
这些是单链表的基本操作,可以根据需要进行调用和组合,实现对链表的创建、插入、删 除、查找和打印等操作。需要注意的是,在使用完链表后,要记得释放节点所占用的内存, 避免内存泄漏。
struct Node* currentNode = head; while (currentNode != NULL && currentNode->data != data) {
currentNode = currentNode->next; } return currentNode; // 返回找到的节点(如果找到) } ```
c语言单链表基本操作
2. 创建链表: ```c struct Node* createLinkedList() {
return NULL; // 返回一个空链表 }

数据结构c语言版单链表心得

数据结构c语言版单链表心得

数据结构c语言版单链表心得单链表是一种常用的数据结构,它能够以链式的形式存储数据,可以动态的插入、删除等操作,非常适合于需要频繁操作数据的场景。

在C语言中,单链表的实现相对来说比较简单,但是需要掌握一些基本的指针操作技巧。

单链表的结构定义通常包含一个数据域和一个指向下一节点的指针域。

例如:```ctypedef struct Node {int data;struct Node* next;} Node;```这里我们定义了一个名为Node的结构体,其中包括一个int类型的数据域和一个指向下一个Node的指针域。

之所以要使用指针域,是因为链表不像数组那样在内存中连续存储,因此我们必须借助指针来建立节点之间的联系。

创建一个链表可以通过动态分配内存来实现,例如:```cNode* create_list() {Node* head = NULL; //头结点Node* tail = NULL; //尾结点int x;while (scanf("%d", &x) != EOF) { //读取数据直到文件末尾Node* node = (Node*)malloc(sizeof(Node)); //动态分配内存node->data = x;node->next = NULL;if (head == NULL) { //如果链表为空head = node; //头结点指向新节点}else {tail->next = node; //尾节点的指针域指向新节点}tail = node; //重置尾节点}return head;}```该函数通过使用malloc动态分配节点内存空间,然后读取数据并将其添加到链表中。

这里head和tail分别指向链表的头结点和尾结点,并且将尾结点的指针域指向新节点。

如果链表为空,则将头结点指向新节点。

遍历链表可以通过循环链表上的节点来实现,例如:```cvoid traverse_list(Node* head) {Node* node = head;while (node != NULL) { //循环链表printf("%d ", node->data);node = node->next; //指向下一个节点}}```该函数以head为参数,循环链表并输出每个节点的数据域。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<iostream.h>
#include<malloc.h>
#include<conio.h>
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define ERROR 0
#define OK 1
typedef int ElemType;
//删除
cout<<"删除操作:\n输入要删除元素的位序:";
cin>>n;
ListDelete(La,n,e);
cout<<"\n要删除的元素值为:"<<e<<endl;
cout<<"删除后表中值有:";
PrintList(La);
init(Lb);
cout<<"请输入Lb表中元素个数:";
cin>>n;
int CreateList(LinkList &L,int n)
{
LinkList p;
L=(LinkList)malloc(sizeof(LNode));
if(!L) return ERROR;
L->next=NULL;
for(int i=n;i>0;i--)
{
p=(LinkList)malloc(sizeof(LNode));
cin>>n;
GetElem(La,n,e);
cout<<endl<<"第"<<n<<"位元素的值为:"<<e<<endl;
//定位
cout<<"定位操作:\n请输入要查找的元素:";
cin>>e;
cout<<endl<<"所要查找的元素在表中第"<<LocateElem(La,e)<<"位\n";
{
LinkList p;
p=La;
int i=0;
while(p->next)
{
p=p->next;
i++;
if(p->data==e)
return i;
}
return 0;
}
//打印表中元素值
void PrintList(LinkList L)
{
LinkList p;
p=L;
while(p->next)
if(!p) return ERROR;
cin>>p->data;
p->next=L->next;L->next=p;
}
return OK;
}
//合并两个有序表
void MergeList(LinkList La,LinkList Lb,LinkList &Lc)
{
LinkList pa,pb,pc;
{
LinkList p; int j;
p=L->next;j=1;
while(p&&j<i)
{
p=p->next;++j;
}
if(!p||j>i) return ERROR;
e=p->data;
return OK;
}
//判断元素e是否在该链表中
int LocateElem(LinkList La,ElemType e)
struct LNODE
{
ElemType data;
struct LNODE *next;பைடு நூலகம்
};
typedef struct LNODE LNode;
typedef struct LNODE *LinkList;
//初始化单链表
int init(LinkList &L)
{
L=(LNode *)malloc(sizeof(LNode));
init(La);
int n;
cout<<"请输入La表中元素个数:";
cin>>n;
cout<<endl<<"请输入"<<n<<"个元素值:";
CreateList(La,n);
PrintList(La);
cout<<"La的表长为:"<<ListLength(La)<<endl;
//取值
cout<<"取第i位元素的值:\n请输入位序:";
}
if(!p||j>i-1) return ERROR;
s=(LinkList)malloc(sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}/*ListInsert Before i */
//删除操作
int ListDelete(LinkList &L,int i,ElemType &e)
{
LinkList p,q;
int j;
p=L;j=0;
while(p&&j<i-1)
{
p=p->next;
++j;
}
if(!p||j>i) return ERROR;
q=p->next;
p->next=p->next->next;
e=q->data;
free(q);
return OK;
}
//头插法建表
getch();
}
{
p=p->next;
cout<<p->data<<ends;
}
cout<<endl;
}
//插入操作
int ListInsert(LinkList &L,int i,ElemType e)
{
LinkList p,s;
int j;
p=L;j=0;
while(p&&j<i)
{
p=p->next;
++j;
free(Lb);
}
void main()
{
LinkList La,Lb,Lc;
ElemType e;
cout<<"\n\n-------------------List Demo is running...----------------\n\n";
cout<<"First is InsertList function.\n";
cout<<endl<<"请输入"<<n<<"个元素值:";
CreateList(Lb,n);
PrintList(Lb);
cout<<"Lb的表长为:"<<ListLength(Lb)<<endl;
cout<<"合并两个有序表:\n";
MergeList(La,Lb,Lc);
PrintList(Lc);
pa=La->next;pb=Lb->next;
Lc=pc=La;
while(pa && pb)
{
if(pa->data<=pb->data)
{
pc->next=pa;pc=pa;pa=pa->next;
}
else
{
pc->next=pb;pc=pb;pb=pb->next;
}
}
pc->next=pa?pa:pb;
if(!L) return(ERROR);
L->next=NULL;
return OK;
}/*init */
//求表长
int ListLength(LinkList L)
{
int j=0;
while (L->next)
{
L=L->next;
j++;
}
return j;
}
//获取表中第i个元素的值
int GetElem(LinkList L,int i,ElemType &e)
相关文档
最新文档