双向链表(C语言版)
链表的c语言实现十

在这里列举了一个应用单链表基本算法的综合程序,双向链表和循环链表的综合程序大家可以自己去试一试。
#include <stdio.h>#include <malloc.h>#include <string.h>#define N 10 typedef struct node{char name[20];struct node *link;}stud;stud * creat(int n){stud *p,*h,*s;int i;if((h=(stud *)malloc(sizeof(stud)))==NULL){printf("不能分配内存空间!");exit(0);}h->name[0]='\0';h->link=NULL;p=h;for(i=0;i<n;i++){if((s= (stud *) malloc(sizeof(stud)))==NULL){printf("不能分配内存空间!");exit(0);}p->link=s;printf("请输入第%d个人的姓名",i+1);scanf("%s",s->name);s->link=NULL;p=s;}return(h);}stud * search(stud *h,char *x){stud *p;char *y;p=h->link;while(p!=NULL){y=p->name;if(strcmp(y,x)==0)return(p);else p=p->link;}if(p==NULL)printf("没有查找到该数据!");}stud * search2(stud *h,char *x){stud *p,*s;char *y;p=h->link;s=h;while(p!=NULL){y=p->name;if(strcmp(y,x)==0)return(s);else{p=p->link;s=s->link;}}if(p==NULL)printf("没有查找到该数据!");}void insert(stud *p){char stuname[20];stud *s;if((s= (stud *) malloc(sizeof(stud)))==NULL) {printf("不能分配内存空间!");exit(0);}printf("\n请输入你要插入的人的姓名:"); scanf("%s",stuname);strcpy(s->name,stuname);s->link=p->link;p->link=s;}void del(stud *x,stud *y){stud *s;s=y;x->link=y->link;free(s);}void print(stud *h){stud *p;p=h->link;printf("数据信息为:\n");while(p!=NULL){printf("%s ",&*(p->name));p=p->link;}}void quit(){exit(0);}void menu(void){clrscr();printf("\t\t\t单链表C语言实现实例\n");printf("\t\t|————————————————|\n"); printf("\t\t| |\n");printf("\t\t| [1] 建立新表|\n");printf("\t\t| [2] 查找数据|\n");printf("\t\t| [3] 插入数据|\n");printf("\t\t| [4] 删除数据|\n");printf("\t\t| [5] 打印数据|\n");printf("\t\t| [6] 退出|\n");printf("\t\t| |\n");printf("\t\t| 如未建立新表,请先建立!|\n"); printf("\t\t| |\n");printf("\t\t|————————————————|\n");printf("\t\t 请输入你的选项(1-6):");}main(){int choose;stud *head,*searchpoint,*forepoint;char fullname[20];while(1){menu();scanf("%d",&choose);switch(choose){case 1:head=creat(N);break;case 2:printf("输入你所要查找的人的姓名:");scanf("%s",fullname);searchpoint=search(head,fullname);printf("你所查找的人的姓名为:%s",*&searchpoint->name); printf("\n按回车键回到主菜单。
[转载整理]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 }。
数据结构c语言版试题及答案

数据结构c语言版试题及答案一、选择题(每题2分,共10分)1. 在C语言中,以下哪个关键字用于定义结构体?A. structB. unionC. enumD. typedef答案:A2. 若有一个结构体数组,下列哪个函数可以用来初始化数组中的每个元素?A. memsetB. memcpyC. strcpyD. bzero答案:A3. 在C语言中,以下哪个函数用于动态分配内存?A. mallocB. callocC. reallocD. all of the above答案:D4. 对于一个链表,以下哪个操作是正确的?A. 插入节点B. 删除节点C. 遍历链表D. all of the above答案:D5. 在C语言中,以下哪个函数用于释放动态分配的内存?A. freeB. mallocC. callocD. realloc答案:A二、填空题(每题3分,共15分)1. 结构体定义的关键字是______。
答案:struct2. 在C语言中,动态分配内存失败时,malloc函数返回______。
答案:NULL3. 单链表的头节点指针通常初始化为______。
答案:NULL4. 双向链表中,每个节点包含______个指针。
答案:两个5. 树的深度优先遍历包括______、中序遍历和后序遍历。
答案:前序遍历三、简答题(每题5分,共20分)1. 请简述C语言中结构体和联合体的区别。
答案:结构体(struct)可以包含不同类型的数据,并且可以有多个实例;联合体(union)可以包含不同类型的数据,但是只能有一个实例,即在任意时刻只能存储其中一个成员的值。
2. 动态内存分配的优点是什么?答案:动态内存分配允许程序在运行时根据需要分配内存,这样可以更有效地使用内存资源,并且可以创建大小不固定的数据结构。
3. 链表相比于数组有哪些优点?答案:链表的优点包括动态大小,可以灵活地插入和删除节点,不需要预先知道数据的大小。
双向链表逆序

双向链表逆序双向链表的逆序操作可以通过修改节点之间的引用关系来实现。
具体步骤如下:1. 定义三个指针:pre表示当前节点的前一个节点,cur表示当前节点,next表示当前节点的后一个节点;2. 遍历整个链表,初始时将pre设置为null,cur设置为链表的头节点;3. 在遍历过程中,先将next指向cur的后一个节点;4. 将cur的next指向pre,将cur的prev指向next。
5. 更新pre和cur,将cur指向next,pre指向cur;6. 重复步骤3~5,直到遍历到链表的最后一个节点。
7. 将最后一个节点的prev指向null,表示链表逆序完成。
以下是Java代码示例:```public class DoublyLinkedList {Node head;class Node {int data;Node prev;Node next;Node(int d) {data = d;prev = null;next = null;}}public void reverse() {Node temp = null;Node current = head;while (current != null) {temp = current.prev;current.prev = current.next;current.next = temp;current = current.prev;}if (temp != null) {head = temp.prev;}}}```注意:逆序之后,原来的头结点会变成尾结点,原来的尾结点会变成头结点。
数据结构考研辅导(潭浩强 C语言版)

第一讲绪论(对应教材p1—p17)一、数据结构1、什么是数据结构我们大家知道许多非数值计算问题的数学模型常常是数学方程,如线性方程组、微分方程。
所以这类非数值计算问题的解决就归结于对数学模型设计算法、编写程序。
然而在现实社会中存在着许多非数值计算问题,其数学模型难以用数学方程描述。
如●图书馆的书目检索自动化问题----计算机处理的对象之间存在着线性关系,称为线性的数据结构。
●人机对奕问题----计算机处理的对象是一个个格局。
所有可能出现的格局是一棵倒置的树。
●多岔路口交通灯的管理问题----数学模型是图的数学结构。
非数值计算问题的数学模型是表、树和图之类的数据结构。
数据结构:是一门研究非数值计算的程序设计问题中计算机操作对象以及它们之间关系和操作的一门学科。
(三个要素:对象、关系及操作(运算))2、《数据结构》课程1968年美国克努特教授开创了数据结构的最初体系:数据的逻辑结构和存储结构及其操作。
数据结构是一门综合性的专业课程,是一门介于数学、计算机硬件、计算机软件之间的一门核心课程。
是设计和实现编译系统、操作系统、数据库系统及其他系统程序和大型应用程序的基础。
二、基本概念和术语1、数据数据:是指所有能输入到计算机中并被计算机程序处理的符号的总称。
是计算机加工的“原料”。
数据元素:是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。
数据项:有时,一个数据元素可由多个数据项组成。
数据项是数据的不可分割的最小单位。
2、数据对象、数据结构数据对象:是性质相同的数据元素的集合,是数据的一个子集。
数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。
四类基本结构:集合、线性结构、树形结构、图形结构或网状结构。
数据结构的形式定义:数据结构是一个二元组Data_Structure=(D,S)其中,D 是数据元素的有限集, S 是D上关系的有限集。
例:复数 Complex=(C,R)例:课题小组 Group=(P,R)P={T,G1,…,Gn,S11,…,Snm}1≤n≤3,1≤m≤2,R={R1,R2}R1={<T,Gi> |1≤i≤n, 1≤n≤3,}R2={<Gi,Sij> |1≤i≤n, 1≤j≤m,1≤m≤2,}数据结构一般包括三方面的内容:①逻辑结构:数据元素之间的逻辑关系。
数据结构 (C语言版) (第二版)(目录)

数据结构(C语言版)(第二版)(目录)第1章导论
1 算法和数据结构
2 什么是数据结构
3 符号,引理,定理与证明
4 说明文篇
5 C语言和程序设计
6 总结
第2章算法分析
1 算法的衡量标准
2 时间和空间复杂度分析
3 运行时复杂度分析
4 递归分析
第3章线性表
1 一维数组
2 线性表
3 顺序表
4 链表
5 循环链表
6 树表
7 双向链表
第4章栈
1 栈的定义
2 栈的抽象数据类型
3 栈的基本操作
4 栈的应用——后缀表达式的求算
第7章树
1 树的定义
2 树的抽象数据类型
3 树的存储
4 树的遍历
5 二叉树
6 二叉排序树(搜索树)
7 平衡二叉树
8 哈夫曼树
9 图的存储
第8章查找
1 静态查找
2 哈希表
3 动态单值查找
第10章数据结构综合应用
1 树的遍历
2 贪心法
3 回溯法
4 分析与评价
附录 A C语言库
1 算法入口及时区函数
2 内存处理函数
3 字符串处理函数
4 文件处理函数
附录 B 内存分配方式。
C语言链表题目及答案

下面哪种选项描述了链表的特点?A) 可以随机访问元素B) 拥有固定大小的内存空间C) 元素之间通过指针连接D) 可以自动调整大小答案: C在链表中,头节点的作用是什么?A) 存储链表的长度B) 存储链表的最后一个节点C) 存储链表的第一个节点D) 存储链表的中间节点答案: C下面哪种选项描述了双向链表的特点?A) 每个节点只有一个指针指向下一个节点B) 每个节点只有一个指针指向上一个节点C) 每个节点同时拥有指向前一个节点和后一个节点的指针D) 只能从链表的一端进行操作答案: C在链表中,删除一个节点的操作涉及修改哪些指针?A) 只需要修改被删除节点的前一个节点的指针B) 只需要修改被删除节点的后一个节点的指针C) 需要修改被删除节点的前一个节点和后一个节点的指针D) 不需要修改任何指针答案: C在链表的尾部添加一个新节点的操作复杂度是多少?A) O(1)B) O(n)C) O(log n)D) O(n^2)答案: A如何遍历链表的所有节点?A) 使用for循环B) 使用while循环C) 使用递归函数D) 使用if语句答案: B在链表中,如何找到特定值的节点?A) 使用线性搜索B) 使用二分搜索C) 使用递归搜索D) 使用栈搜索答案: A链表和数组相比,哪个更适合频繁插入和删除操作?A) 链表B) 数组C) 二叉树D) 堆栈答案: A在链表中,如何在指定位置插入一个新节点?A) 修改前一个节点的指针B) 修改后一个节点的指针C) 修改当前节点的指针D) 不需要修改任何指针答案: A链表的头指针指向什么?A) 链表的第一个节点B) 链表的最后一个节点C) 链表的中间节点D) 链表的空节点答案: A链表中节点的个数称为什么?A) 链表的长度B) 链表的高度C) 链表的宽度D) 链表的容量答案: A在链表中,如何删除指定值的节点?A) 修改前一个节点的指针B) 修改后一个节点的指针C) 修改当前节点的指针D) 不需要修改任何指针答案: A单链表的最后一个节点指向什么?A) 链表的第一个节点B) 链表的最后一个节点C) NULLD) 链表的中间节点答案: C双向链表相比于单向链表的优势是什么?A) 占用更少的内存空间B) 遍历速度更快C) 可以从任意方向遍历D) 插入和删除操作更快答案: C在链表中,如何找到倒数第n个节点?A) 遍历整个链表B) 使用递归函数C) 使用栈数据结构D) 使用双指针技巧答案: D链表的删除操作和数组的删除操作的时间复杂度分别是什么?A) 链表的删除操作为O(1),数组的删除操作为O(n)B) 链表的删除操作为O(n),数组的删除操作为O(1)C) 链表的删除操作为O(n),数组的删除操作为O(n)D) 链表的删除操作为O(1),数组的删除操作为O(1)答案: A在链表中,如何判断链表是否为空?A) 检查头指针是否为NULLB) 检查尾指针是否为NULLC) 检查链表的长度是否为0D) 检查链表的第一个节点是否为NULL答案: A链表的逆序操作是指什么?A) 删除链表中的节点B) 反转链表中节点的顺序C) 插入节点到链表的尾部D) 在链表中查找指定值的节点答案: B在链表中,如何查找指定值的节点?A) 使用线性搜索B) 使用二分搜索C) 使用递归搜索D) 使用栈搜索答案: A在双向链表中,如何删除指定值的节点?A) 修改前一个节点的指针B) 修改后一个节点的指针C) 修改当前节点的指针D) 不需要修改任何指针答案: A链表的插入操作和数组的插入操作的时间复杂度分别是什么?A) 链表的插入操作为O(1),数组的插入操作为O(n)B) 链表的插入操作为O(n),数组的插入操作为O(1)C) 链表的插入操作为O(n),数组的插入操作为O(n)D) 链表的插入操作为O(1),数组的插入操作为O(1)答案: A如何删除单向链表中的重复节点?A) 使用递归算法B) 使用双指针技巧C) 使用栈数据结构D) 不需要额外操作,链表会自动去重答案: B链表的优势之一是什么?A) 随机访问速度快B) 占用内存空间少C) 插入和删除操作高效D) 支持高级操作如排序和搜索答案: C在链表中,如何找到中间节点?A) 遍历整个链表B) 使用递归函数C) 使用栈数据结构D) 使用快慢指针技巧答案: D在链表中,如何在尾部添加一个新节点?A) 修改前一个节点的指针B) 修改后一个节点的指针C) 修改当前节点的指针D) 创建一个新节点并更新尾指针答案: D链表的查找操作的时间复杂度是多少?A) O(1)B) O(log n)C) O(n)D) O(n^2)答案: C在双向链表中,如何找到倒数第n个节点?A) 从头节点开始遍历B) 从尾节点开始遍历C) 使用递归函数D) 使用双指针技巧答案: B链表的删除操作的时间复杂度是多少?A) O(1)B) O(log n)C) O(n)D) O(n^2)答案: A链表和数组相比,哪个更适合频繁插入和删除操作?A) 链表B) 数组C) 哈希表D) 栈答案: A如何判断链表是否有环?A) 使用线性搜索B) 使用递归算法C) 使用快慢指针技巧D) 使用栈数据结构答案: C在链表中,如何反转链表的顺序?A) 使用递归算法B) 使用栈数据结构C) 使用双指针技巧D) 使用循环迭代答案: D在链表中,如何删除所有节点?A) 依次删除每个节点B) 修改头指针为NULLC) 修改尾指针为NULLD) 不需要额外操作,链表会自动清空答案: A链表的头节点是什么?A) 链表的第一个节点B) 链表的最后一个节点C) 链表的中间节点D) 链表的空节点答案: A在链表中,如何插入一个新节点到指定位置之前?A) 修改前一个节点的指针B) 修改后一个节点的指针C) 修改当前节点的指针D) 不需要修改任何指针答案: A在链表中,如何删除指定位置的节点?A) 修改前一个节点的指针B) 修改后一个节点的指针C) 修改当前节点的指针D) 不需要修改任何指针答案: A单向链表和双向链表的区别是什么?A) 单向链表只有一个指针指向下一个节点,双向链表有两个指针分别指向前一个节点和后一个节点B) 单向链表只能从头到尾遍历,双向链表可以从头到尾或者从尾到头遍历C) 单向链表只能在尾部添加节点,双向链表可以在头部和尾部都添加节点D) 单向链表只能包含整型数据,双向链表可以包含任意类型的数据答案: A链表的删除操作和数组的删除操作的时间复杂度分别是什么?A) 链表的删除操作为O(1),数组的删除操作为O(n)B) 链表的删除操作为O(n),数组的删除操作为O(1)C) 链表的删除操作为O(n),数组的删除操作为O(n)D) 链表的删除操作为O(1),数组的删除操作为O(1)答案: A如何判断两个链表是否相交?A) 比较链表的长度是否相等B) 比较链表的头节点是否相等C) 比较链表的尾节点是否相等D) 比较链表中的所有节点是否相等答案: B链表和数组的主要区别是什么?A) 链表是一种线性数据结构,数组是一种非线性数据结构B) 链表的长度可变,数组的长度固定C) 链表支持随机访问,数组只能顺序访问D) 链表的插入和删除操作效率高,数组的访问效率高答案: B在链表中,如何找到倒数第k个节点?A) 从头节点开始遍历,直到倒数第k个节点B) 从尾节点开始遍历,直到倒数第k个节点C) 使用递归函数查找倒数第k个节点D) 使用双指针技巧,一个指针先移动k步,然后两个指针同时移动直到第一个指针到达链表末尾答案: D在链表中,如何判断是否存在环?A) 使用线性搜索,检查是否有重复的节点B) 使用递归算法,判断节点是否已经访问过C) 使用栈数据结构,检查节点是否已经入栈D) 使用快慢指针技巧,如果两个指针相遇,则存在环答案: D如何将两个有序链表合并成一个有序链表?A) 创建一个新链表,依次比较两个链表的节点并插入新链表中B) 将第一个链表的尾节点指向第二个链表的头节点C) 将第二个链表的尾节点指向第一个链表的头节点D) 使用递归算法,依次比较两个链表的节点并合并答案: A在链表中,如何删除重复的节点?A) 使用递归算法,遍历链表并删除重复的节点B) 使用双指针技巧,依次比较相邻节点并删除重复的节点C) 使用栈数据结构,检查节点是否已经入栈并删除重复的节点D) 不需要额外操作,链表会自动去重答案: B链表的优点是什么?A) 占用内存空间少B) 插入和删除操作高效C) 支持高级操作如排序和搜索D) 可以随机访问任意位置的元素答案: B。
lru算法c语言

lru算法c语言LRU算法是Least Recently Used的缩写,即最近最少使用算法。
它是一种用于页面置换的算法,主要用于操作系统中对内存进行管理。
其基本思想是将最近最少使用的页面淘汰掉,从而保留当前正在使用的页面。
在实现LRU算法时,需要使用一个数据结构——双向链表。
链表中每个节点都表示一个页面,其中包含了该页面的编号、访问时间等信息。
当访问一个页面时,如果该页面已经存在于链表中,则将其移到链表头部;如果该页面不存在于链表中,则将其加入链表头部,并删除链表尾部的节点。
以下是C语言实现LRU算法的代码:```c#include <stdio.h>#include <stdlib.h>#define CACHE_SIZE 4typedef struct Node {int data;struct Node* prev;struct Node* next;} Node;Node* head = NULL;Node* tail = NULL;int cache[CACHE_SIZE];int cache_index = 0;void insert(int data) {// 如果缓存未满,则直接插入新节点到双向链表头部 if (cache_index < CACHE_SIZE) {Node* node = (Node*)malloc(sizeof(Node)); node->data = data;node->prev = NULL;node->next = head;if (head == NULL) {tail = node;} else {head->prev = node;}head = node;cache[cache_index++] = data;} else {// 如果缓存已满,则删除双向链表尾部节点,并将新节点插入到头部int last_data = tail->data;Node* last_node = tail;tail = tail->prev;if (tail != NULL) {tail->next = NULL;} else {head = NULL;}free(last_node);Node* node = (Node*)malloc(sizeof(Node));node->data = data;node->prev = NULL;node->next = head;if (head == NULL) {tail = node;} else {head->prev = node;}head = node;for (int i = 0; i < CACHE_SIZE; i++) { if (cache[i] == last_data) {cache[i] = data;break;}}}}void print_cache() {printf("Cache: ");for (int i = 0; i < CACHE_SIZE; i++) { printf("%d ", cache[i]);}printf("\n"); }int main() {insert(1);print_cache();insert(2);print_cache();insert(3);print_cache();insert(4);print_cache();insert(5);print_cache();insert(6);print_cache();return 0;}```在上述代码中,我们使用了一个数组cache来保存当前缓存中的页面编号。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
++j;
}
if(!p||j>i-1)
{
printf("插入失败\n");
return;
}
q=(dullinklist)malloc(sizeof(dulnode));
q->data=e;
//在最后一位插入元素
if(p->next==0)
{
q->next=0;
p->next=q;
q->prior=p;
#include<stdio.h>
//双向链表定义
typedef struct node{
int data;
//数据域
struct node *prior; //前驱
struct node *next;
//后继
}dulnode,*dullinklist;
//初始化
dullinklist initlist()
===================================="); printf("\n删除位置:"); scanf("%d",&i); dellist(l,i,&e); printf("表长:%d\n",listlength(l)); printlist(l); //printf("e=%d\n",e); printf("被删除元素:%d\n",e); printf("======================================END=============== putchar('\n');
{
p->next=q->next;
q->next->prior=p;
}else
p->next=0;
//删除元素位于最后一位
*e=q->data;
free(q);
printf("--删除成功--\n");Βιβλιοθήκη return *e;}
//打印表中元素
void printlist(dullinklist l) {
int count=0;
p=l->next;
//printf("%d",p);
while(p)
{
p=p->next;
count++;
}
return count; //返回表长度
}
//后插法创建双向链表
void createlist(dullinklist l,int n)
{
dullinklist p,r;
//插入新结点
r=p;
//尾结点后移
}
printf("--创建双向链表成功--\n");
}
//插入
void insertlist(dullinklist l,int i,int e)
{
int j=0;
dullinklist p,q;
p=l;
while(p&&j<i-1)
{
p=p->next;
//找寻第i-1个结点
}
printf("--插入成功--\n");
return;
}
//在非最后一位插入元素
q->next=p->next;
p->next->prior=q;
p->next=q;
q->prior=p;
printf("--插入成功--\n");
}
//删除
int dellist(dullinklist l,int i,int *e)
{
int j=0;
dullinklist p,q;
p=l;
//找寻第i-1个结点
while(p&&j<i-1)
{
p=p->next;
j++;
}
if(!p||j>i-1)
{
printf("删除失败\n");
return -1;
}
q=p->next;
//被删除结点
if(q->next)
//删除元素非最后一位
int i=0;
r=l;
//生成新结点
for(;i<n;i++)
{
p=(dullinklist)malloc(sizeof(dulnode)); //生成新结点
printf("输入元素:");
scanf("%d",&p->data);
//输入元素
p->next=0;r->next=p;p->prior=r;
dullinklist p; p=l->next; while(p) {
printf("%3d",p->data); p=p->next; } putchar('\n'); } void main() { int i,e,n; dullinklist l; printf("====================================初始化 ===================================="); putchar('\n'); l=initlist(); printf("表长:%d\n",listlength(l)); printf("=================================创建双向链表 ================================="); putchar('\n'); printf("元素个数:"); scanf("%d",&n); createlist(l,n); printf("表长:%d\n",listlength(l)); printf("======================================插入 ===================================="); printf("\n插入位置:"); scanf("%d",&i); printf("插入元素:"); scanf("%d",&e); insertlist(l,i,e); printf("表长:%d\n",listlength(l)); printlist(l); printf("======================================删除
{
dullinklist l;
l=(dullinklist)malloc(sizeof(dulnode));
l->prior=0;
l->next=0;
printf("--初始化成功--\n");
return l;
}
//表长
int listlength(dullinklist l)
{
dullinklist p;