C++双向循环链表代码(建立、排序、插入、删除)
c语言中linklist类型
c语言中linklist类型LinkList类型是C语言中常用的数据结构之一,它是一种线性链表的实现方式。
在计算机科学中,链表是一种常见的数据结构,用于存储和操作一系列元素。
链表由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。
链表中的第一个节点称为头节点,最后一个节点称为尾节点。
链表可以根据需要动态地增加或删除节点,相比于数组,链表的大小可以根据实际需求进行调整。
链表的实现可以使用不同的方式,其中最常见的是单向链表。
在单向链表中,每个节点只有一个指针,指向下一个节点。
这种实现方式简单且高效,适用于大多数场景。
除了单向链表,还有双向链表和循环链表等其他实现方式。
链表的优点是可以快速在任意位置插入或删除节点,而无需移动其他节点。
这是由于链表中的节点通过指针相互连接,而不是像数组那样连续存储。
另外,链表的大小可以根据需要进行动态调整,而数组的大小是静态的。
这使得链表在处理动态数据集合时非常有用。
然而,链表也有一些缺点。
首先,访问链表中的任意节点都需要从头节点开始遍历,直到找到目标节点。
这导致了链表的访问时间复杂度为O(n),而数组的访问时间复杂度为O(1)。
其次,链表需要额外的内存空间来存储指针信息,这会占用更多的存储空间。
在C语言中,可以使用结构体来定义链表节点,例如:```typedef struct Node {int data;struct Node *next;} Node;typedef struct LinkedList {Node *head;Node *tail;} LinkedList;```上述代码定义了一个包含数据和指针的节点结构体Node,以及一个包含头节点和尾节点指针的链表结构体LinkedList。
通过这样的定义,可以方便地进行链表的操作,比如插入、删除和遍历等。
链表的插入操作可以分为三步:创建新节点、修改指针、更新链表的头尾指针。
例如,插入一个新节点到链表末尾的代码如下:```void insert(LinkedList *list, int data) {Node *newNode = (Node *)malloc(sizeof(Node));newNode->data = data;newNode->next = NULL;if (list->head == NULL) {list->head = newNode;list->tail = newNode;} else {list->tail->next = newNode;list->tail = newNode;}}```链表的删除操作也类似,可以分为三步:找到目标节点、修改指针、释放内存。
例2.2设计一个算法,将x插入到一个有序(从小到大排序)的
SqList *merge(SqList *p, SqList *q) { SqList *r; int i=0,j=0,k=0; r=(SqList *)malloc(sizeof(SqList)); while (i<p->length && j<q->length) { if (p->data[i]<q-> data[j]) { r-> data[k]=p-> data[i]; i++;k++; } else { r-> data[k]=q-> data[j]; j++;k++; } }
本算法实际上是采用尾插法建立两个新表。 所以,尾插法建表算法是很多类似习题的基础!
例2.6 有一个带头结点的单链表head,其ElemType 类型为char,设计一个算法使其元素递增有序。
解:若原单链表中有一个或以上的数据结点 ,先构 造只含一个数据结点的有序表 (只含一个数据结点的 单链表一定是有序表 ) 。扫描原单链表余下的结点 *p( 直到 p==NULL 为止 ), 在有序表中通过比较找插入 *p 的前驱结点 *q, 然后将 *p 插入到 *q 之后 ( 这里实际 上采用的是直接插入排序方法)。
答:可以简单地推算,得容易得出D,A,B,C是 不可能的,因为D先出来,说明A,B,C,D均在栈中, 按照入栈顺序,在栈中顺序应为D,C,B,A,出栈的 顺序只能是D,C,B,A。所以本题答案为D。
例 3.3 已知一个栈的进栈序列是 1,2,3,…,n, 其输出 序列是p1,p2,…,pn,若p1=n,则pi的值 。 (A) i (B) n-i
/*r保存*p结点后继结点的指针*/
[转载整理]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语言版部分习题及答案[2]
第二章习题与解答一判断题1.线性表的逻辑顺序与存储顺序总是一致的。
2.顺序存储的线性表可以按序号随机存取。
3.顺序表的插入和删除操作不需要付出很大的时间代价,因为每次操作平均只有近一半的元素需要移动。
4.线性表中的元素可以是各种各样的,但同一线性表中的数据元素具有相同的特性,因此是属于同一数据对象。
5.在线性表的顺序存储结构中,逻辑上相邻的两个元素在物理位置上并不一定紧邻。
6.在线性表的链式存储结构中,逻辑上相邻的元素在物理位置上不一定相邻。
7.线性表的链式存储结构优于顺序存储结构。
8.在线性表的顺序存储结构中,插入和删除时,移动元素的个数与该元素的位置有关。
9.线性表的链式存储结构是用一组任意的存储单元来存储线性表中数据元素的。
10.在单链表中,要取得某个元素,只要知道该元素的指针即可,因此,单链表是随机存取的存储结构。
二单选题 (请从下列A,B,C,D选项中选择一项)1.线性表是( ) 。
(A) 一个有限序列,可以为空;(B) 一个有限序列,不能为空;(C) 一个无限序列,可以为空;(D) 一个无序序列,不能为空。
2.对顺序存储的线性表,设其长度为n,在任何位置上插入或删除操作都是等概率的。
插入一个元素时平均要移动表中的()个元素。
(A) n/2 (B) n+1/2 (C) n -1/2 (D) n3.线性表采用链式存储时,其地址( ) 。
(A) 必须是连续的;(B) 部分地址必须是连续的;(C) 一定是不连续的;(D) 连续与否均可以。
4.用链表表示线性表的优点是()。
(A)便于随机存取(B)花费的存储空间较顺序存储少(C)便于插入和删除(D)数据元素的物理顺序与逻辑顺序相同5.某链表中最常用的操作是在最后一个元素之后插入一个元素和删除最后一个元素,则采用( )存储方式最节省运算时间。
(A)单链表(B)双链表(C)单循环链表(D)带头结点的双循环链表6.循环链表的主要优点是( )。
(A)不在需要头指针了(B)已知某个结点的位置后,能够容易找到他的直接前趋(C)在进行插入、删除运算时,能更好的保证链表不断开(D)从表中的任意结点出发都能扫描到整个链表7.下面关于线性表的叙述错误的是( )。
c语言实现顺序表的增删查改逆置简单代码
c语言实现顺序表的增删查改逆置简单代码1. 顺序表的定义顺序表是一种线性表,其元素在内存中按顺序存储,每个元素占用连续的存储单元。
顺序表的特点是存取速度快,但插入和删除元素时需要移动大量的元素。
顺序表可以用结构体来表示,其定义如下:typedef struct_SeqList {int*data; // 指向数据元素的指针int size; // 顺序表的长度int capacity; // 顺序表的容量} SeqList;2. 顺序表的初始化顺序表的初始化需要分配内存空间来存放数据元素。
可以使用以下代码来初始化顺序表:SeqList*init_seq_list(int capacity) {SeqList*list= (SeqList*)malloc(sizeof(SeqList));if (list==NULL) {return NULL;}list->data= (int*)malloc(sizeof(int) *capacity);if (list->data==NULL) {free(list);return NULL;}list->size=0;list->capacity=capacity;return list;}3. 顺序表的插入在顺序表中插入元素需要移动后面的元素,以保证元素的顺序性。
可以使用以下代码在顺序表中插入元素:int insert_seq_list(SeqList*list, int index, int value) {if (index<0||index>list->size) {return-1;}if (list->size==list->capacity) {// 扩容顺序表int*new_data= (int*)realloc(list->data, sizeof(int) *list->capacity*2);if (new_data==NULL) {return-1;}list->data=new_data;list->capacity*=2;}// 移动后面的元素for (int i=list->size; i>index; i--) {list->data[i] =list->data[i-1];}// 插入元素list->data[index] =value;list->size++;return0;}4. 顺序表的删除从顺序表中删除元素需要移动后面的元素,以保证元素的顺序性。
2014年郑大《数据结构》在线测试满分题
B、顺序存取
C、插入删除需要移动元素
D、事先估计存储空间的大小
E、插入删除只需要修改指针 4、在双向循环链表(L 为头指针)中,指针 p 所指结点为尾结点的条件是________。
A、p==L
B、p->next==L
C、L->prior==p
D、L->next==p 5、在双向链表中,每个结点有两个指针域,分别指向________。
A、可以是连续的
B、可以是不连续的
C、必须是连续的
D、必须是不连续的 2、在双向循环链表中,若 s 是指向表中某结点的指针,则________。
A、s->next==s
B、s->next->prior==s
C、s->prior->next ==s
D、s-> prior==s 3、顺序表具备的特点有________。
A、其自身
B、其直接前驱结点
C、其直接后继结点
D、头结点 第三题、判断题(每题 1 分,5 道题共 5 分)
1、顺序表能够以元素在计算机内的物理位置的相邻性来表示线性表中元素之间的逻辑关系。
正确 2、在循环链表中设尾指针比设头指针方便。 ( )
错误
正确
错误
3、线性表的顺序存储结构优于链式存储结构。 ( )
C、所含字符个数相同
D、串值相等 4、以下关于串长的说法正确的是__________。
A、串长相等的两个串相等
B、括串值的引号不被计算在串长之内
C、空串的长度为 0
D、空格串的长度为 0 5、以下关于块链结构的说法正确的是__________。
A、结点大小小,则存储密度小
B、结点大小小,则存储密度大
第三题、判断题(每题 1 分,5 道题共 5 分) 1、n 个叶子的 Huffman 树共有 2n-1 个结点。
2024年9月GESP编程能力认证C++等级考试五级真题试卷(含答案)
2024年9月GESP编程能力认证C++等级考试五级真题试卷(含答案)一、单选题(每题2分,共30分)。
1.下面关于链表和数组的描述,错误的是()。
A.数组大小固定,链表大小可动态调整。
B.数组支持随机访问,链表只能顺序访问。
C.存储相同数目的整数,数组比链表所需的内存多。
D.数组插入和删除元素效率低,链表插入和删除元素效率高。
2.通过()操作,能完成在双向循环链表结点p之后插入结点s的功能(其中next域为结点的直接后继,prev域为结点的直接前驱)。
3.对下面两个函数,说法错误的是()。
int sumA(int n){int res=0;for(int i=1;i<=n;i++){res+=i;}return res;}int sumB(int n){if(n==1)return1;int res=n+sumB(n-1);return res;}4.有如下函数fun,则fun(20,12)的返回值为()。
int fun(int a,int b){if(a%b==0)return b;elsereturn fun(b,a%b);}5.下述代码实现素数表的埃拉托斯特尼筛法,筛选出所有小于等于n的素数,则横线上应填的最佳代码是()。
void sieve_Eratosthenes(int n){vector<bool>is_prime(n+1,true);vector<int>primes;for(int i=2;i*i<=n;i++){if(is_prime[i]){primes.push_back(i);________________________________{//在此处填入代码。
is_prime[j]=false;}}}for(int i=sqrt(n)+1;i<=n;i++){if(is_prime[i]){primes.push_back(i);}}return primes;}6.下述代码实现素数表的线性筛法,筛选出所有小于等于n的素数,则横线上应填的代码是()。
数据结构习题
第一章知识点:1.基本概念: 数据结构分类、特点等:如线性结构,是数据元素之间存在一种( 一对一关系)数据元素的概念(数据项)2.时空复杂度1、设有数据结构(D ,R ),其中D={d1,d2,d3,d4,d5,d6},R=r ,r={(d1,d2),(d2,d3),(d3,d4),(d2,d5),(d3,d5)}试按照图论中的画法画出其逻辑结构图。
2、称算法的时间复杂度为O(f(n)),其含义是指算法的执行时间和_【1】_的数量级相同。
3. 计算下面程序段的时间复杂度。
x=0;for(i=1; i<n; i++)for (j=1; j<=n-i; j++)x++;解:因为x++共执行了n-1+n-2+……+1= n(n-1)/2,所以执行时间为O (n 2).4. 计算下面程序段的时间复杂度。
x=n;y=0; 解:设@执行了t(n)次,则(t(n)+1)2<=n ,推出t(n)<=n 1/2-1。
所以时间复杂度为O (n 1/2).5. 分析下面各程序段的时间复杂度 (1) O(n*m) (2) O(log 3n)1)for (i=0; i<n; i++)for (j=0; j<m; j++)A[i][j]=0;2) i=1;while(i<=n) i=i*3;6. 在n 个结点的顺序表中,算法的时间复杂度是O (1)的操作是:A(A )访问第i 个结点(1≤i ≤n )和求第i 个结点的直接前驱(2≤i ≤n ) (B )在第i 个结点后插入一个新结点(1≤i ≤n ) (C )删除第i 个结点(1≤i ≤n ) (D ) 将n 个结点从小到大排序第二章 线性表知识点:顺序表、单链表、双向链表(插入、查找、删除运算)循环链表(单双向)特点, 考点:基本操作、复杂度、特点、算法应用1.在一个单链表中,若p所指结点是q所指结点的前驱结点,则删除结点q的正确操作是( B )A. p->next=qB. p->next=q->nextC. p=q->nextD. p->next=q->next->next2、在一个头指针为head的带头结点单链表中,要向表头插入一个由指针p指向的结点,则应执行【4】p->next=head->next;、【5】head->next=p。
说明---数据结构C语言版 参考代码
各种自定义函数在mylist.h文件中;
test.c是对一些不熟悉的调用进行的测试;
//函数的说明不尽详细,请参照《数据结构(C语言)》版课本;作者为严蔚敏的。
//注意函数调用中的参数----大多是传递的地址,只有赋值的部分用的是传值!!!!
1、线性结构及其操作:
线性表的顺序、链式存储(结构体)以及基本的新建、初始化、插入、删除操作
循环链表、双向链表的实现以及基本(插入、删除)操作
2、树和图的几个图的建立与深度优先递归遍历。。。
暂时不再写了,等过段时间,如果有兴趣可以继续拿着 数据结构(C语言版)课本实现~
数据结构-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指向某结点,都能 删除该结点。
数据结构课程设计
实现二叉树的创建
功能:
D
C
B
A
E
二叉树
方法:
创建二叉树的方法:createTree()
层次遍历的方法:leavelOrder()
计算叶子节点的方法:countLeafNode()
创建哈夫曼树的方法:compareNum()
计算码长的方法:print()
二叉树
思路:
通过从键盘上读取利用先序遍历结果创建一颗二叉树
思路:
01
从键盘上直接输入节点数和节点值添加到链表
03
通过删除方法删除某个位置上的节点
05
建立头节点headNode和尾节点endNode的双向循环链表
02
执行插入方法可以实现某个位上的插入
04
就地逆置通过改变指针指向逆向输出
06
双向循环链表
通过建立一个哈夫曼树,实现哈夫曼算法
计算出二叉树的叶子节点数
通过深度优先遍历来进行图的连通性的判断如果该图是联通的连通分量为其本身,否则输出该图不是连通的并计算出连通分量
有向图
致谢!
层次遍历:通过利用队列思想看访问的节点不是空时进队列,然后访问下一个节点,头一个节点出队列。
通过判断访问节点左右孩子为空来计算叶子节点
通过输入一数组找出该数组中最小的两个,然后相加得到的数为这两个最小数的根节点依次类推,哈弗曼编码是向右拐加1向左拐加0
二叉树
功能:
01
创建一个有向图
02
实现有向图的深度优先遍历
03
实现有向图的广度优先遍历
04
实现实现有向图的增加边的功能
05
实现有向图的删除边的功能
链表(单链表 双向循环)实验报告讲解
数据结构实验报告T1223-3-21余帅实验一实验题目:仅仅做链表部分难度从上到下1.双向链表,带表头,线性表常规操作。
2.循环表,带表头,线性表常规操作。
3.单链表,带表头,线性表常规操作。
实验目的:了解和掌握线性表的逻辑结构和链式存储结构,掌握单链表的基本算法及相关的时间性能分析。
实验要求:常规操作至少有:1.数据输入或建立2.遍历3.插入4.删除必须能多次反复运行实验主要步骤:1、分析、理解给出的示例程序。
2、调试程序,并设计输入数据,测试程序的如下功能:1.数据输入或建立2.遍历3.插入4.删除单链表示意图:headhead head 创建删除双向循环链表示意图:创建程序代码://单链表#include<iostream.h>#include<windows.h>const MAX=5;enum returninfo{success,fail,overflow,underflow,range_error}; int defaultdata[MAX]={11,22,33,44,55};class node{public:int data;node *next;};class linklist{private:node *headp;protected:int count;public:linklist();~linklist();bool empty();void clearlist();returninfo create(void);returninfo insert(int position,const int &item);returninfo remove(int position) ;returninfo traverse(void);};linklist::linklist(){headp = new node;headp->next = NULL;count=0;}linklist::~linklist(){clearlist();delete headp;}bool linklist::empty(){if(headp->next==NULL)return true;elsereturn false;}void linklist::clearlist(){node *searchp=headp->next,*followp=headp;while(searchp->next!=NULL){followp=searchp;searchp=searchp->next;delete followp;}headp->next = NULL;count = 0;}returninfo linklist::create(){node *searchp=headp,*newnodep;for(int i=0;i<MAX;i++){newnodep = new node;newnodep->data = defaultdata[i];newnodep->next = NULL;searchp->next = newnodep;searchp = searchp->next;count++;}searchp->next = NULL;traverse();return success;}returninfo linklist::insert(int position,const int &item) //插入一个结点{if(position<=0 || position>=count)return range_error;node *newnodep=new node,*searchp=headp->next,*followp=headp;for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}newnodep->data=item; //给数据赋值newnodep->next=followp->next; //注意此处的次序相关性followp->next=newnodep;count++; //计数器加一return success;}returninfo linklist::remove(int position) //删除一个结点{if(empty())return underflow;if(position<=0||position>=count+1)return range_error;node *searchp=headp->next,*followp=headp; //这里两个指针的初始值设计一前一后for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}followp->next=searchp->next; //删除结点的实际语句delete searchp; //释放该结点count--; //计数器减一return success;}returninfo linklist::traverse(void){node *searchp;if(empty())return underflow;searchp = headp->next;cout<<"连表中的数据为:"<<endl;while(searchp!=NULL){cout<<searchp->data<<" ";searchp = searchp->next;}cout<<endl;return success;}class interfacebase{public:linklist listface; //定义一个对象Cskillstudyonfacevoid clearscreen(void);void showmenu(void);void processmenu(void);};void interfacebase::clearscreen(void){system("cls");}void interfacebase::showmenu(void){cout<<"================================"<<endl;cout<<" 功能菜单 "<<endl;cout<<" 1.创建链表 "<<endl;cout<<" 2.增加结点 "<<endl;cout<<" 3.删除结点 "<<endl;cout<<" 4.遍历链表 "<<endl;cout<<" 0.结束程序 "<<endl;cout<<"======================================"<<endl;cout<<"请输入您的选择:";}void interfacebase::processmenu(void){int returnvalue,item,position;char menuchoice;cin >>menuchoice;switch(menuchoice) //根据用户的选择进行相应的操作{case '1':returnvalue=listface.create();if(returnvalue==success)cout<<"链表创建已完成"<<endl;break;case '2':cout<<"请输入插入位置:"<<endl;cin>>position;cout<<"请输入插入数据:"<<endl;cin>>item;returnvalue = listface.insert(position,item);if(returnvalue==range_error)cout<<"数据个数超出范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '3':cout<<"输入你要删除的位置:"<<endl;cin>>position;returnvalue = listface.remove(position);if(returnvalue==underflow)cout<<"链表已空"<<endl;else if(returnvalue==range_error)cout<<"删除的数据位置超区范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '4':listface.traverse();break;case '0':cout<<endl<<endl<<"您已经成功退出本系统,欢迎再次使用!!!"<<endl;system("pause");exit(1);default:cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl;break;}}void main(){interfacebase interfacenow;linklist listnow;system("color f0");interfacenow.clearscreen();while(1){interfacenow.showmenu();interfacenow.processmenu();system("pause");interfacenow.clearscreen();}}/* 功能:用双向循环链表存储数据1.创建链表2.增加结点3.删除结点4.遍历链表制作人:余帅内容:239行*/#include<iostream.h>#include<windows.h>const MAX=5;enum returninfo{success,fail,overflow,underflow,range_error}; int defaultdata[MAX]={11,22,33,44,55};class node{public:int data;node * next; //指向后续节点node * pre; //指向前面的节点};class linklist{private:node *headp;protected:int count;public:linklist();~linklist();bool empty();void clearlist();returninfo create(void);returninfo insert(int position,const int &item);returninfo remove(int position) ;returninfo traverse(void);};linklist::linklist(){headp = new node;headp->next = NULL;headp->pre = NULL;count=0;}linklist::~linklist(){clearlist();delete headp;}bool linklist::empty(){if(headp->next==NULL)return true;elsereturn false;}void linklist::clearlist(){node *searchp=headp->next,*followp=headp;while(searchp->next!=NULL){followp=searchp;searchp=searchp->next;delete followp;}headp->next = NULL;headp->pre = NULL;count = 0;}returninfo linklist::create(){node *searchp=headp,*newnodep;for(int i=0;i<MAX;i++){newnodep = new node;newnodep->data = defaultdata[i];newnodep->next = NULL;searchp->next = newnodep;newnodep->pre = searchp;searchp = searchp->next;count++;}searchp->next = headp;headp->pre = searchp;traverse();return success;}returninfo linklist::insert(int position,const int &item) //插入一个结点{if(position<=0 || position>count+1)return range_error;node *newnodep=new node;node *searchp=headp->next,*followp=headp;for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}newnodep->data=item; //给数据赋值newnodep->next = searchp;searchp->pre = newnodep;followp->next = newnodep;newnodep->pre = followp;count++; //计数器加一return success;}returninfo linklist::remove(int position) //删除一个结点{if(empty())return underflow;if(position<=0||position>=count+1)return range_error;node *searchp=headp->next,*followp=headp; //这里两个指针的初始值设计一前一后for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}followp->next=searchp->next; //删除结点的实际语句searchp->next->pre = followp;delete searchp; //释放该结点count--; //计数器减一return success;}returninfo linklist::traverse(void){node *searchp1,*searchp2;if(empty())return underflow;searchp1 = headp;searchp2 = headp;cout<<"连表中的数据为:"<<endl;cout<<"从左至右读取:";while (searchp1->next!=headp ) {searchp1 = searchp1 ->next;cout << searchp1->data<<" ";}cout<<endl;cout<<"从右至左读取:";while (searchp2->pre!=headp ) {searchp2 = searchp2 ->pre;cout << searchp2->data<<" ";}cout<<endl;return success;}class interfacebase{public:linklist listface; //定义一个对象Cskillstudyonface void clearscreen(void);void showmenu(void);void processmenu(void);};void interfacebase::clearscreen(void){system("cls");}void interfacebase::showmenu(void){cout<<"================================"<<endl;cout<<" 功能菜单 "<<endl;cout<<" 1.创建链表 "<<endl;cout<<" 2.增加结点 "<<endl;cout<<" 3.删除结点 "<<endl;cout<<" 4.遍历链表 "<<endl;cout<<" 0.结束程序 "<<endl;cout<<"======================================"<<endl;cout<<"请输入您的选择:";}void interfacebase::processmenu(void){int returnvalue,item,position;char menuchoice;cin >>menuchoice;switch(menuchoice) //根据用户的选择进行相应的操作{case '1':returnvalue=listface.create();if(returnvalue==success)cout<<"链表创建已完成"<<endl;break;case '2':cout<<"请输入插入位置:"<<endl;cin>>position;cout<<"请输入插入数据:"<<endl;cin>>item;returnvalue = listface.insert(position,item);if(returnvalue==range_error)cout<<"数据个数超出范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '3':cout<<"输入你要删除的位置:"<<endl;cin>>position;returnvalue = listface.remove(position);if(returnvalue==underflow)cout<<"链表已空"<<endl;else if(returnvalue==range_error)cout<<"删除的数据位置超区范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '4':listface.traverse();break;case '0':cout<<endl<<endl<<"您已经成功退出本系统,欢迎再次使用!!!"<<endl;system("pause");exit(1);default:cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl;break;}}void main(){interfacebase interfacenow;linklist listnow;system("color f0");interfacenow.clearscreen();while(1){interfacenow.showmenu();interfacenow.processmenu();system("pause");interfacenow.clearscreen();}}运行结果:1.创建链表:2.增加结点3.删除结点心得体会:本次实验使我们对链表的实质了解更加明确了,对链表的一些基本操作也更加熟练了。
双向链表上的插入和删除算法
编写程序,演示在双向链表上的插入和删除算法。
问题分析:1、在双向链表上操作首先要生成一个双向链表:1>节点定义struct DuLNode{ElemType data;DuLNode *prior;DuLNode *next;};2.> 创建双列表L=(DuLinkList)malloc(sizeof(DuLNode));L->next=L->prior=L;3>输入链表数据;2、3、对向链表进行插入操作算法:在节点p的前面加入一个新的节点q:q=(DuLinkList)malloc(sizeof(DuLNode));q->data=e;q->prior=p->prior;q->next=p;p->prior->next=q;p->prior=q;4、对双向链表进行删除操作算法删除给定节点p得到的代码如下:#include<iostream>#include<malloc.h>#define OK 1#define ERROR 0using namespace std;typedef int ElemType;typedef int status;struct DuLNode{ ElemType data;DuLNode *prior;DuLNode *next;};typedef DuLNode *DuLinkList;status DuListInsert_L(DuLinkList L,int i , ElemType e)//插入函数{DuLinkList p=L; //定义两个指向头节点的指针DuLinkList q=L;int j=0;while(p->next!=L&&j<i) //判断p是否到最后一个数据{p=p->next;j++;}if(p->next==L||j<i) //如果p是最后一个节点或者插入位置大于链表节点数{printf("无效的插入位置!\n");return ERROR;}//创建新节点q,数据为e,指针为nullq=(DuLinkList)malloc(sizeof(DuLNode));q->data=e;q->prior=p->prior;q->next=p;p->prior->next=q;p->prior=q;return OK;}status DuListDelete_L(DuLinkList L,int i , ElemType &e)//删除{DuLinkList p=L;int j=0;while(p->next!=L&&j<i){p=p->next;j++;}if(p->next==L||j<i){return ERROR;}p->prior->next=p->next;p->next->prior=p->prior;e=p->data;free(p);return OK;}int main(){ //初始化双向循环链表LDuLinkList L;L=(DuLinkList)malloc(sizeof(DuLNode)); //创建空双列表头结点L->next=L->prior=L;DuLNode *p,*q;ElemType e;//给L赋初始值p=L;q=L;while(cin>>e){p->next=(DuLNode*)malloc(sizeof(DuLNode));//分配新的节点q=p;p=p->next; //p指向新的节点p->data=e; //新结点的数据域为刚输入的ep->next=L; //新结点的指针域为头结点,表示这是单链表的最后一个结点p->prior=q;L->prior=p;}//p指向头指针,逐一输出链表的每个结点的值p=L;while(p->next!=L) //输出原列表{cout<<p->next->data<<' ';p=p->next;}cin.clear(); //清除上一个cin的错误信息cin.ignore(); //清空输入流int i;cout<<"输入待插入的元素e:";cin>>e;cout<<"输入待插入的位置i:";cin>>i;if(DuListInsert_L(L,i,e)){cout<<"插入后的双链为:";p=L;while(p->next!=L){cout<<p->next->data<<' ';p=p->next;}}printf("\n");p=L;while(p->next!=L) //输出列表{cout<<p->next->data<<' ';p=p->next;}int k;cin.clear(); //清除上一个cin的错误信息cin.ignore(); //清空输入流cout<<"要删除第几个节点k :";cin>>k;if(DuListDelete_L(L,k,e)){cout<<"被删除的元素为:"<<e<<endl;cout<<"删除后的元素为:";p=L;while(p->next!=L) //输出删除后的列表{cout<<p->next->data<<' ';p=p->next;}}elsecout<<"删除出错";return 0;}得到的结果如图罗达明电科一班学号2010301510028 2013、3、17。
数据结构c语言版(题目)
分类:编程思想和算法2012-09-15 22:24 1759 人阅读评论(0)收藏举报如果TCPhashlistJuli 采用线性表的顺序存储结构,则可以随机存取表中任一终端,但插入和删除终端时,需要移动大量元素,巧妙地终端离线不进行删除操作。
数组,存储的元素应该是线性表顺序存储结构的数据结构。
线性表题目类型:线性表在顺序结构上各种操作的实现;线性链表的各种操作;两个或多个线性表的各种操作;循环链表和双向链表;稀疏多项式及其运算在线性表的两种存储结构上的实现。
线性表在顺序结构上各种操作的实现题目1:(线性表顺序存储结构上的操作—Delete )从顺序存储结构的线性表a 中删除第i个元素起的k个元素。
(《数据结构题集C语言版》P16)题目2:(线性表顺序存储结构上的操作_lnsert )设顺序表va中的数据元素递增有序。
试写一算法,将x插入到循序表的适当位置上,以保持该表的有序性。
(《数据结构题集C语言版》P17)题目3:(线性表顺序存储结构上的操作_逆置)试写一算法,实现顺序表的就地逆置,即利用原表的存储空间将线性表逆置。
(《数据结构题集C语言版》2.21)线性表线性链表的各种操作题目1:( Insert )试写一算法,在无头结点的动态单链表上实现线性表的Insert(L,i,b), 并和在带头结点的动态单链表上实现同样操作的算法进行比较。
(《数据结构题集C语音版》P17)题目2:(Delete )同上题要求,实现线性表操作Delete(L,i).题目3:已知线性表中的元素以值递增有序排序,并以单链表作为存储结构。
试写一高效算法,删除表中所有值大于mink且小于maxk的元素(若表中存在这样的元素)同时释放被删除结点空间,并分析你的算法的事件复杂度(注意:mink和maxk是给定的两个参变量,它们的值可以和表中的元素相同,也可以不同)。
(《数据结构题集C语言版》P17)题目4:同上题条件,试写一高效算法,删除表中所有值相同的多余元素(使得操作后的线性表所有元素的值均不相同),同是释放被删结点空间,并分析你算法的时间复杂度。
例2.2设计一个算法,将x插入到一个有序(从小到大排序)的
例2.4 已知长度为n的线性表A采用顺序存储结 构,编写一个时间复杂度为O(n)、空间复杂度为O(1) 的算法,该算法删除线性表中所有值为item的数据元 素。 解 : 用 k 记录顺序表 A 中等于 item 的元素个数 , 边 扫描A边统计k,并将不为item的元素前移k个位臵,最 后修改A的长度。对应的算法如下:
}
void delnode2(SqList &A,ElemType item) { int k=0,i=0; /*k记录值等于item的元素个数*/ while (i<A.length) { if (A.data[i]==item) k++; 算法2
else A.data[i-k]=A.data[i]; /*当前元素前移k个位臵*/
SqList *merge(SqList *p, SqList *q) { SqList *r; int i=0,j=0,k=0; r=(SqList *)malloc(sizeof(SqList)); while (i<p->length && j<q->length) { if (p->data[i]<q-> data[j]) { r-> data[k]=p-> data[i]; i++;k++; } else { r-> data[k]=q-> data[j]; j++;k++; } }
i++;
for (j=L->length-1;j>=i;j--) L->data[j+1]=L->data[j]; L->data[i]=x; L->length++; }
数据结构复习题
数据结构复习题第一章抽象数据类型数据结构基本要素数据逻辑结构------集合、线性、树型、图数据存储结构------- 顺序、链接、散列、索引算法及其分析----时间复杂度,空间复杂度,O()练习题1 数据结构形式地定义为(D,R),其中D是_________的有限集合,R是D上的_________ 有限集合。
2 数据结构包括数据的____________、数据的_______________和数据的___________三个方面的内容。
3 计算机算法指的是()A. 计算方法B. 排序方法C. 解决问题的有限运算序列D. 调度方法4 在数据结构中,从逻辑上可以把数据结构分为()A. 动态结构和静态结构B. 紧凑结构和非紧凑结构C. 线性结构和非线性结构D. 内部结构和外部结构5 数据结构在计算机内存中的表示是()A. 数据的存储结构B. 数据结构C. 数据的逻辑结构D. 数据元素之间的关系第二章线性表----(直接)前驱、(直接)后继抽象数据类型-----插入操作、删除操作顺序表-----数据元素存储地址的计算链接表(插入+删除)----结点结构:数据域+ 指针域,单链表,双向链表,循环链表链表中头结点的用途习题1设有一线性表e=(e1, e2, …, en),其逆线性表定义为e’=(en, en-1, …, e2,e1)。
请设计一个算法,将用顺序表表示的线性表逆置,要求逆线性表仍占用原线性表的存储空间。
2写一个算法,在带头结点的单链表list中,删除p所指的结点,并返回成功与否的标志。
3一个长度为n的线性表,在其第i个元素(1≤i≤n)之前插入一个元素时,需向后移动____________个元素;删除第i个元素时,需要向前移动____________个元素。
4链表不具备的特点是()A. 可随机访问任一结点B. 插入删除不需要移动元素C. 不必事先估计存储空间D. 所需空间与其长度成正比5 如果最常用的操作是取第i个结点及其前驱,则采用()存储方式最节省时间。
2023年武汉工程大学研究生考试自命题真题 836计算机综合I(数据结构、计算机组成原理)
武汉工程大学2023年全国硕士研究生招生考试考试科目代码及名称:836计算机综合I一、选择题(本大题共40小题,每小题2分,共80分)1.数据的四种存储结构是______。
A、顺序存储结构、链式存储结构、索引存储结构和散列存储结构B、线性存储结构、非线性存储结构、树型存储结构和图型存储结构C、集合存储结构、一对一存储结构、一对多存储结构和多对多存储结构D、顺序存储结构、树型存储结构、图型存储结构和散列存储结构2.下列函数中,n为问题规模,其对应的时间复杂度最小的是______。
n+7789nA、T1(n)=2023log2B、T2(n)=225nlogn-9978n2n+1117n2-5321nC、T3(n)=2023nlog2D、T4(n)=2023n3+31115n3.关于线性表的存储结构,以下叙述中错误的是______。
A、线性表的顺序存储结构中隐式地存储了数据元素之间的逻辑关系B、线性表的顺序存储结构一定需要占用一片连续的存储空间C、线性表的链式存储结构通过指针来反映数据元素之间的逻辑关系D、线性表的链式存储结构占用的存储空间一定不连续4.在一个有n个元素的顺序表中,随机删除一个元素,平均需要移动个元素______。
A、nB、n-1C、n/2D、(n-1)/25.在双向循环链表中删除指针D1指向结点(非两端结点),其中prev和next分别是指向对应结点的直接前驱和直接后继结点的指针,应执行的操作为______。
A、D1->prev->next=D1->next;D1->next->prior=D1->prior;B、D1->piev=D1->next;D1->next=D1->prior;C、D1->next->prio=D1->next;D1->next=D1->prior;D、D1->prior->next=D1->next;D1->prior=D1->next;6.下列关于“字符串”及其应用的叙述中不正确的是______。
计算机程序设计思想
相关算法
3.定位 定位:确定给定元素x在表L中第一次出现的位置(或序号)。即实现Locate(L,x)。 定位 算法对应的存储结构如图所示。 算法思路:设一扫描变量i(初值=0),判断当前表中元素ai是否等于x,若相等, 算法思路 则返回当前i值(表明x落在表的第i位置);否则i加1,继续往下比较。若表中 无一个元素与x相等,则返回-1 。 L->data 0 a0 算法描述: 算法描述
学 号 姓 名 丁兰 王林 ------马红 性 别 女 男 ------女 年 龄 19 20 ------18 班 级 计06 计06 ------计06 -------------------------------
a0 a1
..
J06001 J06002 ------J06032
..
a31
线性表的特征: 线性表的特征: 对非空表(a 对非空表 0, ········ai-1aiai+1······an-1) a0是表头 无前驱;an-1是表尾 无后继;其它的每个元素 i有且仅有一个 是表头,无前驱 无前驱; 是表尾,无后继 其它的每个元素a 无后继; 直接前驱(a 和一个直接后继 和一个直接后继(a 。 直接前驱 i-1)和一个直接后继 i+1)。
2.3 线性表的链式存储结构
2.3.1指针变量的物理意义 指针变量的物理意义 计算机的内存空间是由连续编号的内存单元构成,每个内存单元具有唯 一的地址(编号)。在以字节编址的计算机系统中,每个内存单元存放 一个字节。 变量的2个要素:地址,值 地址由系统自动分配,所占空间的大小由类型决定 指针变量与其它变量一样,在定义之后,系统自动分配相应的内存空间 以存放其值。 指针变量的值是指针,即地址。
大学计算机《数据结构》试卷及答案(十四)
大学计算机《数据结构》试卷及答案一、选择题(24分)1.下列程序段的时间复杂度为( )。
i=0,s=0; while (s<n) {s=s+i ;i++;}(A) O(n 1/2) (B) O(n 1/3) (C) O(n) (D) O(n 2)2.设某链表中最常用的操作是在链表的尾部插入或删除元素,则选用下列( )存储方式最节省运算时间。
(A) 单向链表(B) 单向循环链表 (C) 双向链表(D) 双向循环链表 3.设指针q 指向单链表中结点A ,指针p 指向单链表中结点A 的后继结点B ,指针s 指向被插入的结点X ,则在结点A 和结点B 插入结点X 的操作序列为( )。
(A) s->next=p->next ;p->next=-s ; (B) q->next=s ; s->next=p ;(C) p->next=s->next ;s->next=p ; (D) p->next=s ;s->next=q ;4.设输入序列为1、2、3、4、5、6,则通过栈的作用后可以得到的输出序列为( )。
(A) 5,3,4,6,1,2(B) 3,2,5,6,4,1 (C) 3,1,2,5,4,6 (D) 1,5,4,6,2,35.设有一个10阶的下三角矩阵A (包括对角线),按照从上到下、从左到右的顺序存储到连续的55个存储单元中,每个数组元素占1个字节的存储空间,则A[5][4]地址与A[0][0]的地址之差为( )。
(A) 10 (B) 19 (C) 28 (D) 556.设一棵m 叉树中有N 1个度数为1的结点,N 2个度数为2的结点,……,Nm 个度数为m 的结点,则该树中共有( )个叶子结点。
(A) (B) (C) (D)7. 二叉排序树中左子树上所有结点的值均( )根结点的值。
(A) < (B) > (C) = (D) !=∑=-m i i N i 1)1(∑=m i i N 1∑=m i i N 2∑=-+m i i N i 2)1(18. 设一组权值集合W=(15,3,14,2,6,9,16,17),要求根据这些权值集合构造一棵哈夫曼树,则这棵哈夫曼树的带权路径长度为()。
C语言实现循环链表
C语⾔实现循环链表本⽂实例为⼤家分享了C语⾔实现循环链表的具体代码,供⼤家参考,具体内容如下注意事项:1、循环链表设置尾指针。
由于在链表的操作过程中,尾指针会不断变化,所以在⼀些函数的形参中都设置指向头指针的指针。
以及链表的结束判断条件变成q是否等于尾指针。
2、注意传递的实参需要取地址3、循环链表的优势在于双链表合并,以及实现尾插法简单(⾸先新建结点指向头结点,然后把尾指针的next域指向该新建结点)4、在创建链表时,使⽤尾插法,⽽不是⽤头插法(因为头插法很难去更新尾指针,使得最后尾指针还需额外更新⼀次),直接⽤头插法建⽴的是头指针,⽽⾮尾指针代码:#include<stdio.h>#include<stdlib.h>typedef struct Node{int data;struct Node * next;}Node, *LinkList;LinkList Creat();void Destroy(LinkList *L);void Insert(LinkList *L, int val, int index);void Delete(LinkList *L, int index);void Traverse(LinkList L);int main(){LinkList L = Creat();Traverse(L);Insert(&L, 1, 5);printf("After inserting is :\n");Traverse(L);printf("After deleting is :\n");Delete(&L, 2);Traverse(L);Destroy(&L);Traverse(L);}LinkList Creat(){LinkList L = (LinkList)malloc(sizeof(Node));//⽤L指针指向新建结点,这⾥L还不算尾指针int n;L->data = -1;L->next = L;//头结点的指针域指向头结点, 注意!这⾥是对尾指针的初始化。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
k=p;
for(q=p->next;q!=L;q=q->next)
if((k->data)>(q->data)) k=q;
if(k!=p){
if(p->next==k||k->prior==p){ //判断k是p的后续结点
p->prior->next=k;
L->prior->next=t;
t->prior=L->prior;
q->next=L;L->prior=q;
}
return 1;
}
void array(Dulinklist &L)
//按升序排列双向链表
{
Dulinklist p,q,t1,t2,k;
for(p=L;p->next!=L;p=p->next)
shuchulist(La);
}else printf("删除失败,未找到 %d\n",c);
break;
case 4: printf("升序排列后为:\n");
array(La);
shuchulist(La);
printf("请输入需要插入的值X ");
/*
编写一个完整的程序,实现双向循环链表的基本操作
(1)利用尾插法建立一个双向循环链表。
(2)遍历双向循环链表。
(3)实现双向循环链表中删除一个指定元素。
(4)在非递减有序双向循环链表中实现插入元素e仍有序算法。
(5)判断双向循环链表中元素是否对称若对称返回1否则返回0。
(6)设元素为正整型,实现算法把所有奇数排列在偶数之前。
else printf("双向链表不对称\n\n");
break;
case 6: initlist(Lb);
t=pailie(La);
if(t){
printf("重排后为:\n");
shuchulist(La);
}else printf("重排失败!\n");
L->data=0;
L->next=L;
L->prior=L;
return 1;
}//初始化了一个空表
void createlist(Dulinklist &L) //尾插法生成双向链表
{
Dulinklist p,t;
t=L;
printf("尾插法:请输入双向链表节点值,以输入0结束。\n");
int menu,c,t;
initlist(La);
do{
printf("1 利用尾插法建立一个双向循环链表\n");
printf("2 遍历双向循环链表\n");
printf("3 实现双向循环链表中删除一个指定元素\n");
printf("4 在非递减有序双向循环链表中实现插入元素e仍有序算法\n");
if(p==L) L=p->next; //如果偶结点为主链头结点头指针后移一位
p->prior->next=p->next;
p->next->prior=p->prior;
if(t) {
q->next=p;
p->prior=q;
q=p;
{
printf(" %d",p->data);
i++;
}
printf(" %d\n",p->data);
printf("双向链表的长度为 %d\n\n",i);
}
Dulinklist GetElem(Dulinklist L,int x)
//获取双向链表中值为X的结点指针
k->prior=p->prior;
k->next->prior=p;
p->next=k->next;
p->prior=k;
k->next=p;
}else if(p->prior==k||k->next==p){ //判断p是k的后续结点
p->next->prior=k;
//删除链表L中的值为X的结点
{
Dulinklist p;
int flag;
flag=0;
while(p=GetElem(L,x)){
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);
flag=1;
break;
case 0: exit(0);
default: printf("所输入的菜单Biblioteka 不正确! \n\n");
}
}while(menu);
p->prior->next=k;p->next->prior=k;
t1=k->next;t2=k->prior;
k->next=p->next;k->prior=p->prior;
p->next=t1;p->prior=t2;
}
if(p==L) L=p=k;
t->data=x;
while(p->data<x&&p->next!=L)
p=p->next;
if(p->next==L&&p->data<x){ //判断尾结点比X小则将t放到p后
t->next=p->next;t->prior=p;
p->next->prior=t;p->next=t;
t=p;
}
L->prior=t->prior;
t->prior->next=L;
}
void shuchulist(Dulinklist L)
//通过链表的遍历来输出链表中的信息
{
int i;
Dulinklist p;
printf("双向链表为:");
for(p=L,i=1;p->next!=L;p=p->next)
(7)在主函数中设计一个简单的菜单调试上述算法。
*/
#include <stdio.h>
#include <stdlib.h>
typedef int elemtype;
typedef struct DuLNode //定义结点类型
{
elemtype data;
struct DuLNode *prior;
menu=7;
if(scanf("%d",&menu)==EOF) menu=7;
switch(menu)
{
case 1: initlist(La);//如果初始化成功,则创建该链表。
printf("建立双向链表L——尾插法建立");
createlist(La);
}
if(flag) return 1;
else return 0;
}
int duichen(Dulinklist L)
//判断双向循环链表中元素是否对称若对称返回1否则返回0
{
Dulinklist p,q;
int flag;
flag=1;
p=L;
q=L->prior;
return flag;
}
int pailie(Dulinklist &L)
//设元素为正整型,实现算法把所有奇数排列在偶数之前。
{
Dulinklist t,p,q;
t=q=NULL;
p=L;
while(p->next!=L){
if(p->data%2==0)
{
}else{
t=q=p;
}
}
p=p->next;
}
if(p->data%2==0){ //判断尾结点的奇偶性
p->prior->next=p->next;
p->next->prior=p->prior;
if(t) {
q->next=p;
scanf("%d",&t->data);
while(t->data!=0)
{
p=(Dulinklist)malloc(sizeof(DuLNode));
if(!p) exit(-2);
t->next=p;
p->prior=t;
scanf("%d",&p->data);
scanf("%d",&c);
intolist(La,c);
printf("插入后的链表为:\n");
shuchulist(La);
break;
case 5: shuchulist(La);