循环双向链表
cy24 线性表--循环链表解读

2)链表: n 个结点由指针链组成一个链表。 它是线性表的链式存储映像, 称为线性表的链式存储结构。 3)单链表、双链表、循环链表: • 结点只有一个指针域的链表,称为单链表或线性链表 • 有两个指针域的链表,称为双链表(但未必是双向链表) • 首尾相接的链表称为循环链表。
拓展:静态链表 静态链表借用一维数组来描述线性链表。数组中 的一个分量表示一个结点,同时使用游标(指示器cur即 为伪指针)代替指针以指示结点在数组中的相对位置。 数组中的第0个分量可以看成头结点,其指针域指示静 态链表的第一个结点。 这种存储结构仍然需要预先分配一个较大空间,但 是在进行线性表的插入和删除操作时不需要移动元素, 仅需要修改“指针”,因此仍然具有链式存储结构的主 要优点。
下图给出了一个静态链表的示例。图(a)是一个修改之前的 静态链表,图(b)是删除数据元素“陈华”之后的静态链表,图(c) 插入数据元素“王华”之后的静态链表,图中用阴影表示修改 的游标。
数据域 0 1 2 3 4 5 6 7 8 9 (a) 张斌 刘丽 李英 陈华 王奇 董强 王萍 游标域 1 2 3 4 5 6 7 0 0 1 2 删除“陈华” 3 4 5 6 7 8 9 (b) 张斌 刘丽 李英 陈华 王奇 董强 王萍 数据域 游标域 1 2 3 5 5 6 7 0 0 1 在 “刘丽” 之后 2 插入“王华” 3 4 5 6 7 8 9 (c) 王奇 董强 王萍 王华 6 7 0 3 张斌 刘丽 李英 数据域 游标域 1 2 8 5
例:实现将两个线性表heada(a1,a2,a3,…an)和 headb(b1,b2,b3,…bn)链接成一个线性表的运算。 假设线性表为单循环链表。 linklist connect(linklist heada,linklist headb) //若heada,headb分别指向表头结点 { linklist p=heada->next; while (p->next!=heada) p=p->next; //p指向表a的尾结点 p->next=headb->next; //链接表a、b while (p->next!=headb) p=p->next; free(headb); p->next=heada; 讨论: return(heada); 有没有更快的方法? }
[转载整理]C语言链表实例
![[转载整理]C语言链表实例](https://img.taocdn.com/s3/m/0aca427eb94ae45c3b3567ec102de2bd9605debe.png)
[转载整理]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 }。
循环双链表特点

循环双链表特点循环双链表是一种特殊的数据结构,它具有循环和双向链表的特点。
循环双链表中的每个节点都包含两个指针,一个指向前一个节点,一个指向后一个节点。
最后一个节点的后指针指向头节点,头节点的前指针指向最后一个节点,从而形成了一个闭环。
循环双链表的特点如下:1. 双向性:每个节点都有两个指针,分别指向前一个节点和后一个节点。
这样可以方便地在任意位置插入或删除节点,而不需要像单链表那样需要遍历找到前驱节点。
2. 循环性:循环双链表是一个闭环,即最后一个节点的后指针指向头节点,头节点的前指针指向最后一个节点。
这样可以方便地进行循环遍历,不需要判断是否到达了链表的末尾。
3. 动态性:循环双链表可以动态地增加或删除节点,而不需要预先指定链表的长度。
4. 灵活性:循环双链表可以在任意位置插入或删除节点,不受限于只能在链表的头部或尾部进行操作。
这样可以方便地实现栈、队列等数据结构。
5. 代码实现简单:相比于其他数据结构,循环双链表的代码实现相对简单,只需要处理好节点之间的指针关系即可。
循环双链表的应用领域非常广泛,特别是在需要频繁插入和删除节点的场景中,循环双链表能够提供高效的插入和删除操作。
下面以几个具体的应用场景来展开对循环双链表的解释和扩展。
1. 缓存替换算法:循环双链表可以用于实现LRU(Least Recently Used)缓存替换算法。
LRU算法中,当缓存满时,需要替换掉最近最少使用的数据。
循环双链表可以维护数据的访问顺序,每次访问一个数据时,将其移到链表的头部;当缓存满时,删除链表尾部的数据即可。
这样就可以保证链表头部的数据是最近访问的数据,尾部的数据是最久未访问的数据。
2. 轮播图:循环双链表可以用于实现轮播图功能。
轮播图需要循环展示多张图片,循环双链表正好可以满足这个需求。
每个节点表示一张图片,节点之间通过指针连接起来形成一个循环链表。
通过不断地遍历链表,可以实现图片的自动切换。
3. 约瑟夫环问题:循环双链表可以用于解决约瑟夫环问题。
循环链表

2、循环链表import java.io.*;class student {public String name;public int score;public student next;}class CircularList{static student ptr,head,current,prev;static DataInputStream infile;static DataOutputStream outfile;CircularList(){head =new student();head.next=head;}public static void anykey_f(){char tChar;System.out.println(" Press any key to continue...");try{tChar=(char)System.in.read();}catch(IOException e){}}public static void load_f(){boolean done=false;System.out.print("File loading...");try{infile =new DataInputStream(new FileInputStream("circularlist.dat"));}catch(IOException e){System.err.println("failed!");System.err.println("circularlist.dat not found!");return;}while(done==false){ptr=new student();try{=infile.readUTF();ptr.score=infile.readInt();}catch(EOFException eof){done =true;}catch(IOException e){}if(done==true)ptr=null;}System.out.println("OK!");try{infile.close();}catch(IOException e){}}public static void save_f(){student node;System.out.print("File saving...");try{outfile =new DataOutputStream(new FileOutputStream("circularlist.dat"));}catch(IOException e){System.out.println("failed!");return;}node=head.next;do{try{outfile.writeUTF();outfile.writeInt(node.score);}catch(IOException e){}node=node.next;}while(node!=head);System.out.println("OK!");try{outfile.close();}catch(IOException e){}}public static void insert_f() {DataInputStream in =new DataInputStream(System.in);String st=" ";ptr=new student();System.out.println("\n\n************Insert Node************\n");System.out.print(" Please enter student name:");System .out.flush();try{=in.readLine();} catch (IOException e){}System.out.print("Please enter student score:");System.out.flush();try{st=in.readLine();}catch(IOException e) {}try{ptr.score=Integer.valueOf(st).intValue();} catch(NumberFormatException e){}System.out.println("\n*************************************\n\n");prev=head;current=head.next;if(current!=null){while((current!=head)&&(current.score>=ptr.score)){prev=current;current=current.next;}}ptr.next=current;prev.next=ptr;}public static void delete_f() {DataInputStream in =new DataInputStream(System.in);String del_name="";int count=0;if(head.next==null)System.out.println("\n\n No student record!!\n");else{System.out.println("\n\n************Delete Node************\n");System.out.print(" Delete student name:");System.out.flush();try{del_name=in.readLine();}catch(IOException e) {}prev=head;current=head.next;while((current!=head)&&(!(del_name.equals()))){prev=current;current=current.next;}if(current !=null){prev.next=current.next;current=null;System.out.print("Student"+del_name+"record deleted\n");}elseSystem.out.print("Student"+del_name+"not found\n");}anykey_f();System.out.println("\n*************************************\n\n");}public static void modify_f() {DataInputStream in =new DataInputStream(System.in);int count=0;String n_temp="",st="";if(head.next==null)System.out.println("\n\n No student record!!\n");else{System.out.println("\n\n************Modify Node************\n");System.out.print(" Modify student name:");System.out.flush();try{n_temp=in.readLine();}catch(IOException e) {}current=head.next;do{if(n_temp.equals()){System.out.println("\n*************************************\n\n");System.out.print("Student name:"++"\n");System.out.print("Student score:"+current.score+"\n");System.out.println("\n*************************************\n\n");System.out.print(" Please enter new score:");System.out.flush();try {st =in.readLine();}catch (IOException e){}try {current.score=Integer.valueOf(st).intValue();}catch (NumberFormatException e){}count++;}current=current.next;}while (current !=head);if (count>0)System.out.println("\n "+count +"student record(s) modified !!\n");elseSystem.out.println ("\n Student "+n_temp +"not found !!\n");}anykey_f();System.out.println("\n******************************\n\n");}public static void dispiay_f(){int count=0;if(head.next==null)System.out.println ("\n\n NO student record !!\n");else {System.out.println("\n\n*************Dispiay Node ************\n");System.out.println(" NAME SCORE");System.out.println("-------------------------------");current=head.next;do{System.out.print(" "+current .name+" ");System.out.println(current .score);count++;current=current.next;if(count % 20 ==0)anykey_f();}while (current!=head);System.out.println("-------------------\n");System.out.println(" Total "+count +"record(s) found!!\n");}anykey_f();System.out.println("***************************\n\n");}public static void main (String args[]){DataInputStream in =new DataInputStream(System.in);String op="";int option=0;CircularList obj =new CircularList();load_f();do{System.out.println("****** CircularList Program *****");System.out.println(" ");System.out.println(" <1> Insert Node ");System.out.println(" <2> Delete Node ");System.out.println(" <3> Modify Node ");System.out.println(" <4> List Node ");System.out.println(" <5> Exit ");System.out.println(" ");System.out.println("***********************************");System.out.println("\n Choice :");System.out.flush();op="";try{op=in.readLine();}catch (IOException e){}option=0;try{option=Integer.valueOf(op).intValue();}catch (NumberFormatException e){System.out.println("\n Please input (1,2,3,4,5) ...");}switch(option){case 1:obj.insert_f();break;case 2:obj.delete_f();break;case 3:obj.modify_f();break;case 4:obj.dispiay_f();break;case 5:obj.save_f();System.exit(0);}}while (true);}}3、双向链表import java.io.*;class student {public String name ="";public int score=0;public student llink;public student rlink;}class DoubleList{static student prev,ptr,head,current;static DataInputStream infile;static DataOutputStream outfile;DoubleList (){ptr = new student (); = "0";ptr.llink = ptr;ptr.rlink = ptr;head = ptr ;}public static void anykey_f(){char tChar;System.out.println(" press any key to continue ... ");try {tChar = (char) System.in.read () ;} catch (IOException e) {}}public static void load_f(){boolean done =false;System.out.print("File loading...");try{infile=new DataInputStream(new FileInputStream("dblink.dat"));} catch(IOException e) {System.err.println("failed!");System.err.println("dblink.dat not found!");return;}while(done==false){ptr=new student();try{=infile.readUTF();ptr.score=infile.readInt();}catch(EOFException eof){done=true;}catch(IOException e){}if(done==true)ptr=null;}System.out.println("OK!");try{infile.close();}catch(IOException e){}}public static void save_f(){student node;System.out.print("File saveing...");try{outfile=new DataOutputStream(new FileOutputStream("dblink.dat"));}catch(IOException e){System.out.println("failed!");return;}node=head;do{try{outfile.writeUTF();outfile.writeInt(node.score);}catch(IOException e){}node=node.rlink;}while(node!=head);System.out.println("OK!");try{outfile.close();}catch(IOException e) {}}public static void insert_f(){DataInputStream in = new DataInputStream(System.in);String name_t="" , st="";ptr = new student();System.out.print("\n please enter student name : ");System.out.flush();try { = in.readLine();} catch (IOException e) {}System.out.print(" please enter student score: ");System.out.flush();try {st = in.readLine();} catch (IOException e) {}try {ptr.score = Integer.valueOf (st).intValue();} catch (NumberFormatException e) {}System.out.println("");prev = head;current = head.rlink;while ((current != head) && (current.score >= ptr.score)) {prev = current;current = current.rlink;}ptr.rlink = current;ptr.llink = prev;prev.rlink = ptr;current.llink = ptr;}public static void delete_f(){DataInputStream in=new DataInputStream(System.in);String del_name="";int count =0;student clear;if(head.rlink==head)System.out.println("\n No student record !!");else{System.out.print("\n Delete student name:");System.out.flush();try{del_name=in.readLine();}catch (IOException e){}prev=head;current=head.rlink;while((current.rlink!=head)&&(! del_name.equals())){ prev=current;current=current.rlink;}prev.rlink=current.rlink ;current.rlink.llink=prev;current=null;System.out.println("Student "+del_name +"record(s) deleted!\n");}if (current==head){System.out.println("Student "+del_name +"not found!\n");}anykey_f();}public static void modify_f(){DataInputStream in=new DataInputStream(System.in);int count=0;String n_temp="",s_temp="";if(head.rlink==head)System.out.println("\n No student record !!");else{System.out.print("\n Modify student name: ");System.out .flush();try{n_temp=in.readLine();}catch(IOException e){}current=head.rlink;while(current!=head){if(n_temp.equals()) {System.out.println("\n ***************************");System.out.println(" Student name:"+);System.out.println(" Student score:"+current.score);System.out.println(" ***************************\n");System.out.print("Please enter new score:");System.out.flush();try{s_temp=in.readLine();}catch (IOException e) {System.out.println(e);}try{current.score=Integer.valueOf(s_temp).intValue();} catch(NumberFormatException e){System.out.println(e);}count++;}current=current.rlink;}if(count>0)System.out.println(" "+count+"student record(s) modified!!\n"); elseSystem.out.println(" Student"+n_temp+"not found!!\n");}anykey_f();}public static void display_f(){int count=0;if(head.rlink==head)System.out.println("\n No student record!!");else{System.out.println("\n NAME SCORE");System.out.println(" --------------------------");current=head.rlink;while(current!=head){System.out.println(" "++" "+current.score);count++;current=current.rlink;if(count%20==0)anykey_f();}System.out.println("--------------");System.out.println(" Total"+count+"record(s)found!!\n");}anykey_f();}public static void main (String args[]){DataInputStream in=new DataInputStream(System.in);String op="";int option=0;DoubleList DBLink =new DoubleList();load_f();do{System.out.println("******* Double Link Program ********");System.out.println(" ");System.out.println(" <1>Insert Node ");System.out.println(" <2>Delete Node ");System.out.println(" <3>Modify Node ");System.out.println(" <4>List Node ");System.out.println(" <5>Exit ");System.out.println(" ");System.out.println("**************************************");System.out.print(" \n choice: ");System.out.flush();op="";try {op=in.readLine();} catch (IOException e) {System .out.println(e);}option=0;try {option=Integer.valueOf(op).intValue();}catch (NumberFormatException e){System.out.println("\n Please input (1,2,3,4,5)...");System.out.println ("\n\n\n");}switch (option){case 1:insert_f();break;case 2:delete_f();break;case 3:modify_f();break;case 4:display_f();break;case 5:save_f();System.exit(0);}}while(true);}}4、多项式相加import java.io.*;class Poly{public int coef;public int exp;Poly next;};class Poly_add{public Poly ptr,eq_h1,eq_h2,ans_h;public static void main(String args[]){Poly_add obj=new Poly_add();System.out.print("************************************\n");System.out.print("--Polynomial add using format ax^b--\n");System.out.print("************************************\n");System.out.println("\n<< Please enter the first equation(enter 0 to exit input) >>\n");obj.eq_h1=obj.input();System.out.println("\n<< Please enter the second equation(enter 0 to exit input) >>\n");obj.eq_h2=obj.input();obj.poly_add();System.out.println("");obj.show_poly(obj.eq_h1,"The first equation:");obj.show_poly(obj.eq_h2,"The second equation:");obj.show_poly(obj.ans_h,"The answer equation:");}public Poly input(){Poly eq_h =null,prev=null;String temp;DataInputStream in=new DataInputStream(System.in);while(true){ptr=new Poly();ptr.next=null;System.out.print("Enter coefficient...");try{ptr.coef=Integer.valueOf(in.readLine()).intValue();}catch(IOException e){}if(ptr.coef==0)return eq_h;System.out.print("Enter exponent...");try{ptr.exp=Integer.valueOf(in.readLine()).intValue();}catch(IOException e){}if(eq_h==null)eq_h=ptr;elseptr.next=ptr;prev=ptr;}}public void poly_add(){Poly this1,this2,prev;this1=eq_h1;this2=eq_h2;prev=null;while(this1 !=null|| this2!=null){&& ptr=new Poly();ptr.next=null;if((this1 !=null && this2!==null)||this1 != null&& this.exp >this2.exp){ptr.coef=this1.coef;ptr.exp=this1.exp;this1=this1.next;}elseif(this1 !=null || this1.exp<this2.exp){ptr.coef=this2.coef;ptr.exp=this2.exp;this2=this2.next;}else{ptr.coef=this1coef+this2.coef;ptr.exp=this1.exp;if(this1 !=null)this1=this1.next;if(this2 !=null)this2=this2.next;}if(ptr.coef !=0){if (ans_h==null)ans_h=ptr;elseprev.next=ptr;pre=ptr;}elseptr=null;}}public oid show_poly(Poly head,String text){Poly node;node=head;System.out.print(text);while(node!=null){System.out.print(node.coef+"x^"+node.exp);if(node.next!=null && node.next.coef>=0)System.out.print("+");node=node.next;}System.out.print("\n");}}。
双向链表

第8讲 双向链表● 循环单链表的出现,虽然能够实现从任一结点出发沿着链能找到其前趋结点,但时间耗费是O (n) 。
● 如果希望从表中快速确定某一个结点的前趋,另一个解决方法就是在单链表的每个结点里再增加一个指向其前趋的指针域prior 。
这样形成的链表中就有两条方向不同的链,我们称之为双向链表。
● 双向链表的结构定义如下:typedef struct DNode{ ElemType data ;struct DNode *prior ,*next ;}DNode, * DoubleList ;● 双向链表的结点结构如图所示。
图:双链表的结点结构注:● 双向链表也是由头指针唯一确定的,● 增加头结点能使双链表的某些运算变得方便● 由于在双向链表中既有前向链又有后向链,寻找任一个结点的直接前驱结点与直接后继结点变得非常方便。
● 设指针p 指向双链表中某一结点,则有下式成立:p->prior->next = p = p->next->prior●在双向链表中,那些只涉及后继指针的算法,如求表长度、取元素、元素定位等,与单链表中相应的算法相同,● 但对于前插和删除操作则涉及到前驱和后继两个方向的指针变化,因此与单链表中的算法不同。
1、 双向链表的前插操作【算法思想】欲在双向链表第i 个结点之前插入一个的新的结点,则指针的变化情况如图所示:… p …s->prior=p->prior; ①p->prior->next=s;②s->next=p; ③p->prior=s;④【算法描述】int DlinkIns(DoubleList L,int i,ElemType e){DNode *s,*p;… /*先检查待插入的位置i是否合法(实现方法同单链表的前插操作)*/… /*若位置i合法,则找到第i个结点并让指针p指向它*/s=(DNode*)malloc(sizeof(DNode));if (s){ s->data=e;s->prior=p->prior; ①p->prior->next=s; ②s->next=p; ③p->prior=s; ④r eturn TRUE;}else return FALSE;}2、双向链表的删除操作【算法思想】欲删除双向链表中的第i个结点,则指针的变化情况如图所示:p->prior->next=p->next; ①p->next->prior=p->prior; ②free(p);【算法描述】int DlinkDel(DoubleList L,int i,ElemType *e){DNode *p;… /*先检查待插入的位置i 是否合法(实现方法同单链表的删除操作)*/… /*若位置i 合法,则找到第i 个结点并让指针p 指向它*/*e=p->data;p->prior->next=p->next; ①p->next->prior=p->prior; ②free(p);return TRUE;}3、 双向循环链表双向链表可以有循环表,称为双向循环链表。
数据结构-chap2 (3)循环链表

head->next=NULL; while(p!=NULL) {r=p->next; head->next=p; p=r; } return(head); }∥invert
∥p为工作指针,指向第一个元素
∥臵空链表 ∥将原链表的元素按头插法插入 ∥暂存p的后继 ∥头结点的指针域指向新插入的结点 ∥恢复待处理结点
A.插入、删除不需要移动元素
B.可随机访问任一元素 C.不必事先估计存储空间 D.所需空间与线性长度成正比
试述头指针、头结点、元素结点、首元结点的区别。 单链表中,增加一个头结点的目的是为了( )。 【江苏大学 2005 一.3(2分)】 A.使单链表至少有一个结点 B.标识表结点中首结点的位臵
C.方便运算的实现
【解答】单循环链表中无论设置尾指针还是头指针都可以
遍历到表中任一个结点。设置尾指针时,若在表尾进行插 入元素或删除第一元素,操作可在O(1)时间内完成;若只 设置头指针,在表尾进行插入或删除操作,需要遍历整个 链表,时间复杂度为O(n)。
在循环链表中寻找结点的直接后继很简单,只需要O(1); 但要寻找结点的直接前趋需要循环一遍,需要O(n)。
C. (p->rlink)->llink=p
D. p->rlink=(p->llink)->llink
p->rlink=(p->rlink)->rlink
p->llink=(p->rlink)->rlink;
【西安电子科技大学 1998 一、1(2分)】
试述头指针、头结点、元素结点、首元结点的区别。 •在单链表、双链表、单循环链表中,若知道指针p指向某结点, 能否删除该结点,时间复杂度如何? 【解答】以上三种链表中,若知道指针p指向某结点,都能 删除该结点。
删除双向循环链表中结点P的前驱结点

题目:试编写一个在循环双向链表中进行删除操作的算法,要求删除的结点是指定结点p的前趋结点。
代码:#include<stdio.h>#include<stdlib.h>#define LEN sizeof(struct List)struct List{int data;struct List *next,*prior;};void print(struct List *head)//输出链表的函数{struct List *p;p=head;if(head!=NULL)do{printf("%5d",p->data );p=p->next ;}while(p!=NULL);}int main(){struct List *head,*q,*p,*m,*p1,*p2;int n=0;p1=(struct List*) malloc(LEN);//创建一个新的双向循环链表printf("请输入一个以0为结束的双向循环链表的元素: ");scanf("%d",&p1->data);head=NULL;while(p1->data!=0){n=n+1;if(n==1)head=p1;elsep2->next=p1;p1->prior =p2;p2=p1;p1=(struct List *)malloc(LEN);//开辟动态存储区,把起始地址赋给p1scanf("%d",&p1->data);}p2->next=head;head->prior =p2;p=head;int i;printf("输入结点P所在位置i: "); scanf("%d",&i);if(i==1) //删除结点P的前驱结点{p2->prior->next =NULL;}else if(i==2){head=head->next;p2->next =NULL;}else{for(i;i>1;--i){q=p;p=p->next;}q->prior->next =p;p->prior =q->prior ;p2->next =NULL;}printf("删除后的链表元素为: ");print(head);printf("\n");return 0;}。
数据结构习题与实验指导

第一部分习题第一章绪论一.单选题1.若一个数据具有集合结构,则元素之间具有()。
A.线性关系B.层次关系C.网状关系D.无任何关系2.下面程序段的时间复杂度为()。
int i,j;for(i=0;i<m;i++)for(j=0;j<n;j++)a[i][j]=i*j;A.O(m2) B.O(n2) C.O(mхn) D.O(m+n)3.执行下面程序段时,S语句被执行的次数为()。
int i,j;for(i=1;i<=n;i++)for(j=1;j<=i;j++)S;A.n2B.n2/2 C.n(n+1) D.n(n+1)/2二.填空题1.数据的逻辑结构被分为_____________、_____________、_____________和_____________四种。
2.数据的存储结构被分为_____________、_____________、_____________和_____________四种。
3.在线性结构、树结构和图结构中,前驱和后继结点之间分别存在着_____________、_____________和_____________的联系。
4.在C语言中,一个数组a所占有的存储空间的大小即数组长度为_____________,下标为i的元素a[i]的存储地址为_____________。
5.在下面程序段中,s=s+p语句的执行次数为_____________,p*=j语句的执行次数为_____________,该程序段的时间复杂度为_____________。
int i=0,s=0;while(++i<=n){ int j,p=1;for(j=1;j<=i;j++) p*=j;s=s+p;}6.某算法仅含2个语句,其执行次数分别为1000n2和0. 01n3,则该算法的时间复杂度为_____________。
7.一个算法的时间复杂度为(3n2+2nlog2n+4n-7)/(5n),其数量级表示为__________。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <stdio.h>#include "Dlink.h"int main(void){DLink *L;int i = 0;ElemType e = '0';//认真体会C语言拷贝传递的思想InitList(&L);InsElem(L, 'a', 1);InsElem(L, 'b', 2);InsElem(L, 'c', 3);InsElem(L, 'd', 4);InsElem(L, 'e', 5);printf("线性表");DispList(L);printf("长度:%d/n",GetLength(L));i = 3;GetElem(L, i, &e);printf("第%d个元素:%c/n", i, e);e = 'a';printf("元素%c是第%d个元素/n", e, Locate(L, e));i = 4;printf("删除第%d个元素/n", i);DelElem(L, i);printf("线性表:");DispList(L);/**/return 0;}[cpp] view plaincopyprint?#ifndef DLINK#define DLINKtypedef char ElemType;typedef struct node{ElemType data;struct node *prior, *next;}DLink;void InitList(DLink **L); //初始化运算int GetLength(DLink *L); //求表长运算int GetElem(DLink *L, int num, ElemType *e); //求线性表中第i个元素运算int Locate(DLink *L, ElemType x); //按值查找运算int InsElem(DLink *L, ElemType x, int i); //插入节电运算int DelElem(DLink *L, int num); //删除结点运算void DispList(DLink *L); //输出线性表#endif[cpp] view plaincopyprint?#include <stdio.h>#include "Dlink.h"#include <malloc.h>/************************************************** 函数名:void InitList(DLink **L)** 功能:初始化线性表运算** 描述:无** 作者:/***/*************************************************/void InitList(DLink **L){*L = (DLink *)malloc(sizeof(DLink));(*L)->prior = (*L)->next = *L;}/************************************************** 函数名:int getLength(DLink *L)** 功能:获取链表的长度** 描述:无** 作者:/***/*************************************************/int GetLength(DLink *L)int i = 0;DLink *p = L->next;while(p != L){i++;p = p->next;}return i;}/************************************************ ** 函数名:int GetElem(DLink *L, int num, ElemType *e) ** 功能:求线性表中第i个元素运算** 描述:出错返回-1,成功返回0** 作者:/***/*************************************************/int GetElem(DLink *L, int num, char *e){int j = 1;DLink *p = L->next;if(num < 1 || num > GetLength(L)){return -1;}while(j < num){p = p->next;j++;}*e =p->data;return 0;}/************************************************ ** 函数名:int Locate(DLink *L, ElemType x)** 功能:求某元素在线性表中的位置** 描述:出错返回-1,成功返回位于线性表第几个元素** 作者:/***/*************************************************/int Locate(DLink *L, ElemType x){DLink *p = L->next;int i = 1; //起始位置1//while(i < GetLength(L) && p->data != x)while(p != L && p->data != x){p = p->next;i++;}if(p == L){return -1;}else{return i;}}/************************************************** 函数名:int InsElem(DLink *L, ElemType x, int num)** 功能:在线性表某个位置插入某元素** 描述:出错返回-1** 作者:/***/*************************************************/int InsElem(DLink *L, ElemType x, int num){DLink *p = L,*s;//s = (DLink *)malloc(sizeof(DLink));int j = 1;s = (DLink *)malloc(sizeof(DLink)); //这句必须放在int j = 1;定义的后面,VC6使用的非C99标准,定义必须放前面if(num < 1 || num > GetLength(L) + 1) //注意考虑可以插入在最后一位,所以是GetLength(L)+1{free(s);return -1;}s->data = x;while(j < num) //指向待插入位置前一个结点{p = p->next;j++;}s->next = p->next;s->next->prior = s;s->prior = p;p->next = s;return 0;}/************************************************ ** 函数名:int DelElem(DLink *L, int num)** 功能:删除线性表某位置的元素** 描述:出错返回-1** 作者:/***/*************************************************/int DelElem(DLink *L, int num){DLink *p = L, *q;int j = 1;if(num < 1 || num > GetLength(L)){return -1;}while(j < num) //指向待删除元素的前一个结点{p = p->next;j++;}q = p->next; //指向待删除元素q->next->prior = p;p->next = q->next;free(q);return 0;}/************************************************ ** 函数名:void DispList(DLink *L)** 功能:输出线性表** 描述:无** 作者:/***/*************************************************/void DispList(DLink *L){DLink *p = L->next;while(p != L){printf("%c ",p->data);p = p->next;}printf("/n");}。