20222c语言电子-c7道cc面试题_第1页
20222c语言电子-c7道cc面试题_第2页
20222c语言电子-c7道cc面试题_第3页
20222c语言电子-c7道cc面试题_第4页
20222c语言电子-c7道cc面试题_第5页
已阅读5页,还剩46页未读, 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第10 数据结数据结构用来反映一个数据的组成。数据的组成是指数据由哪些分子数据构成、以什么样的形式来构成、呈什么样的结构。数据结构的设计的目的是提高算法效率。通常数据结构和一组算法的集合相对应,而很多算法就是对数据结构施行的一种变换。本章将详细讲解数据结构相关的常见面试考题。链表是一种基础的数据结构,是一种特殊线性表,因为它并不是按线性顺序数据数据物理结数组中的数据在内存中,按顺序在一块连续的空间上,时就要确定长度。而链表动态地进行分配,链表可可以是连续的,也可以是不连续的,链表的结构如10.1所示。图 链表物理结数组和链表的优点数组——可以按下标索引来数组中的元素,速度比较快。不用保存相邻结点链表——链表在,删除操作上有很高的效率(相对数组)。大小动态分配,数组和链表的缺点数组——进行或删除操作非尾部数据时,需要移动很多元素,所以对数组进行或删除操作效率很低。事先定义固定的长度(元素个数),不能适应数据动态元素为止,所以链表的随机的效率要比数组要低。链表还要保存结点指针,增加了对空间的需求。typedeftypedefstructNODE{intstructnode}NODE*middle(lnode{NODE{return}//fast是快指针,slow慢指针,p{}return//////f}next指针指向它前面的一个元素,最后尾结点成了头结点,10.210.5。10.210.310.410.5pretempcur中,然nextnextNULL。temppre,curtemp,curcurnextnextpretemp。temp所指结点就是反序后的链表首结点。ListList{{return}listcur=n.next;listpre=n;listtmp;pre.next=null;while(NULL!=cur.next{tmp=tmp.next=prepre=tmp;////循环直到cur.next//10.310.5cur=}return//f}ListList*reverse(List*oldList,List*newHead=NULL{List*next=oldList->oldList->next=newHead;newHead=oldList;return(next==NULL)?newHead:reverse(t,newHead}10.210.5成一个环,可以从链表中的任一结点出发,链表中的所有结点。单链表的这一优点,设计一个程序,用键盘输入的一些数字创建一个单向循环链表,求出链表长度,打印链表各个元后可以根据需求把这个循环链表改装成单向链表或者是带环的单向链表10.6所示。10.6typedeftypedefstruct{intstructnode////LinkList LLinkListpl= pl–>next= 10.710.7LinkListp=(LinkList)malloc(sizeof(structnode));////LinkListp=(LinkList)malloc(sizeof(structnode));////图10.8一个新结点的单向循环链重复、操作,直到输入结束。便完成了循环链表的创建任务LinkListtemp=L- while(temp->next!=L-{}p1while(temp->next!=L-{}

10.9for(intfor(intm=0;m<LinkListLengh-{p1=p1-}if(if(i=={p1->next=NULL;}for(m=0;m<ifor(m=0;m<i-1{p2=p2-}p1->next=10.10voidvoid{LinkListL;inticout<<"请输入从第几个元素开始循环(0为非循环单链表):"<<endl; i=0LinkListp1,p2;p1=L->next;p2=p1->next->next;while(i<25){cout<<p1->data<<"";p1=p1->next;p2=p2->next-}}pleasepleaseinputthedataofthenodeinput0toend:1pleaseinputthedataofthenodeinput0toend:2pleaseinputthedataofthenodeinput0toend:3pleaseinputthedataofthenodeinput0toend:4pleaseinputthedataofthenodeinput0toend:5pleaseinputthedataofthenodeinput0toend:6pleaseinputthedataofthenodeinput0toend:0TheListIs:23456链表长度为请输入从第几个元素开始循环请输入从第几个元素开始循环3123456345634563456345634typedeftypedefstruct{intstructnodevoidCreatLinkList(LinkList{inti;LinkListpl;L=(LinkList)malloc(sizeof(structnode));pl=L;cout<<"pleaseinputthedataofthenode<<"input0toend:";{//LinkListp=(LinkList)malloc(sizeof(structnode)){cout<<"alloctationerror"<<endl;}//cout<<"pleaseinputthedataofthenode<<"input0toend:";}}voidPrintLinkList(LinkList //LLinkListtemp=L->next;cout<<"TheListIs{{}}intLinkListLengh(LinkList{intLinkListtemp=L->next;{}return}voidLinkListCircle(LinkList&L,inti,int{LinkListp1=p2=L-for(intm=0;m<LinkListLengh-{p1=p1-}if(i=={p1->next=NULL;}for(m=0;m<i-1{p2=p2-}p1->next=}5next指向空时,证明这个链表就是不带环的单向链表。或者快指针等于慢指针,证明LinkListp1, p1=p2=(p1->next)-nextp1=p2=(p1->next)-p2p1向后移动一个结点,p2向后移动两个结点。p1等于p2则证明这是一个带环的单向链表,结束返回。否则到(2)。10.11所示。10.1110.1210.12boolboolresearch_cycleLink(LinkList{LinkListp1,p2;boolresult=false;p1=if(p1->next=={}}elseif(p1->next->next=={}{p2=(p1->next)-while((p1!=NULL)&&(p2!={if(p1=={result=}{if(p2->next=={result=false;}p1p1- p2(p2->next)- }}//end}return}一个数组,每向数组添加一个新的结点元前遍历数组,看看数组中是否已有相同的结点,如果已有,则证明这个结点就是环的起点,否则继续遍历,直到链表有环或者下个结点为NLL。虽然这些方法便于理解和想到,但是当链表很大时,会占用很多的空间并且会有大量的比较(相对于本例而言),所以是不足取的。next方向顺序的遍历链表,直到找到指定的结点。在一条非常大的链表中,用这6根据键盘输入的数据创建一个双向链表。同创建单链表一样,首先创建一个结点的结所示:typedefstruct{int//structdnod//structdnod//LinkList LinkListpl= 然后让pl指向的next和pre两个指针都指向NULL,形成一个只有一个首结点的空双pl= 10.1410.14s=(s=(LinkList)malloc(sizeof(dnod));s->data=x;p->next=s;s->pre=s->next=p=////图10.15一个新结点后的双向链重复操作,直到输入结束。便完成了双向链表的创建任务LinkListpLinkListp=L-p11p1nextwhile(pwhile(p!={p=p-}10.9NULL,具体操作参照链表长度计算。#include<stdio.h>#include#include<stdio.h>#include<malloc.h>voidmain(void){LinkList inkList(L//printf("Lengthoflistis:%d\n",LenthLinkList(L)PrintLinkList(L}pleasepleaseinputthedataofthenodeinput0toend:1pleaseinputthedataofthenodeinput0toend:2pleaseinputthedataofthenodeinput0toend:3pleaseinputthedataofthenodeinput0toend:0Lengthoflistis:typedeftypedefstruct{intstructdnod*next;structdnod*pre;//////voidvoid inkList(LinkList&{LinkListp,s;intx,cycle=1;pLinkList)malloc(sizeof(dnod ifp {printf("Failtomalloctheheadnode!\n");}p->pre=NULL;p->next=NULL;L=p;while(cycle{printf("pleaseinputthedataofthenode\n");printf("input0toend:");if(x!={s=(LinkList)malloc(sizeof(dnod));if(s==NULL){printf("Failtomallocanewnode!\n");return; }}s->data=x;p->next=s;s->pre=s->next=p=//将新结 链}{cycle=}}return}voidvoidPrintLinkList(LinkList{if(L->next=={printf("ThelistLisNULL\n");}LinkListp=L->next;while(p!=NULL){if(p->next=={}p=p-}}////intintLenthLinkList(LinkList{inti=0;LinkListp;p=L->next;while(p!=NULL){if(p->next=={}p=p-}return}注意:当指针作为形参传递时,一定要先检验指针的,然后再使用。在动态面试题7:编程实现双链表新结一个已知链表,根据给定的位置、数据实现一个新结点的在链表结入新结点,首先要定位尾结点,可分以下几步LinkListLinkListp1=while(while(p1->next!=NULLp1p1=p1-判断p1是否到达链表尾结点。是则新结点,否则回到while(while(p1->next!=NULL{p1=p1-}p2->next=p1->next;p2->pre->next=p1;p2->pre=p1;p1->next=找到尾结点后,只需要将原尾结点的next指针指向新的结点,而新的结点的p2->next=p1->next;p2->pre->next=p1;p2->pre=p1;p1->next=10.16图10.16尾部新结点的示意在链表中间某个位置新结点LinkListp1= while(p1->next!=NULL p1=p1- if(p1->next==NULL{printf("Thenumyougivenistolarge!\n");return;}if(p1->next==NULL{printf("Thenumyougivenistolarge!\n");return;}判断当前结点是否为要结点的位置,是则返回此结点,否则回while(while(i<num{p1=p1-}找到新结点要的位置后,只需要将新结点的next指针指向原结点,原结点的pre的next指向新的结点。而新的结点的pre指针指向原结点的pre,原结点的pre指p2->nextp2->next=p1->next;p2->pre->next=p1;p2->pre=p1->next= 10.17

图10.17链表中间某个位置新结点的示意voidvoidInsertNode(LinkList&L,intnum,intdata{inti=1;LinkListp1,p2;p1=L;p2=(LinkList)malloc(sizeof(dnod)if(p2=={printf("Failtomallocanewnode!\n");return;}p2->data=data;if(num==0){while(p1->next!=NULL{p1=p1-}p2->next=p1->next;p2->pre->next=p1;p2->pre=p1;p1->next=}{while(i<num {{ifp1->nextNULL {printf("Thenumyougivenistolarge!\n");return;}p1=p1-}p2->next=p1->next;p2->pre->next=p1;p2->pre=p1;p1->next=}}3指定位置新结点,只要设置好位置即可。如。InsertNode(L,1,56)就是在双向链表L的第一个结点位置添加data56可。如:InsertNode(L,0,56)就是在双向链表L的尾部添加data值为56的新结点。8LinkListp1= while(p1->next!=NULL p1=p1- while(p1->next!=NULLwhile(p1->next!=NULL{p1=p1-},找到尾结点后只需要将原尾结点pre指向结点的next指向NULL原尾结点的内p2p2=p1-p1->next=p2->next;p2=10.1810.18在双向链表删除中间某个位置的结LinkListp1= while(p1->next!=NULL p1=p1- if(p1->nextif(p1->next==NULL{printf("Thenumyougivenistolarge!\n");return; while(i<while(i<num{p1=p1-}nextpre指针指向当前preprenextnext指针所p2p2=p1-p1->next=p2->next;p2->next->pre=p1;p2=

10.19voidvoidDeleteNode(LinkList&L,intnum{if(L->next==NULL{printf("ThelistLisNULL\n");}inti=LinkListp1,p2;p1=L;if(if(num=={while(p1->next->next!=NULL{p1=p1-}p2=p1-p1->next=p2->next;p2->next->pre=p1;p2=}{while(i<num{if(p1->next==NULL{printf("Thenumyougivenistolarge!\n");return;}p1=p1-}p2=p1-if(p2->next!={p2->next->pre=}p1->next=p2->next;p2->next->pre=p1;p2=}}除双向链表L的第一个结点。当指定长度为列表长度时,删除的是尾结点。在不知道链表长度时,也可删除尾结点,只要把删除位置设置为0DeleteNode(L,0)L抽象数据类型。由于它们广泛应用在各种系统中,如在面象的程序设计中,它们9栈栈:可以看作是只能在表的一端进行和删除操作的线性表队列:可以看作是只能在表的一端进行而只能在另一端进行删除操作的线性从结构来看,它们都是线性结构,即数据元间的关系相同。但它们是完全不性表相比,它们的和删除操作有的约束和限定,所以又被称为限定性的线性表结构。线性表的实现如图10.20:图10.20线性表数10.21Insert(Insert(L,num,dataDelete(L,numL是作的线性表,num作的位置(num小于表长length),data入点的数栈的和删除实现如图图10.22栈的和删除实push(push(L,datapop(LL是作的栈,data是入的数据值,新结点放置在栈顶。pop的是栈中最后队列的删除实现如图图10.23队列的和删除实push(L,push(L,dataL是作的队列,data是入的数据值,放在队首。pop的是队列中最早的数队列和栈都是线性结构,但是两者的和删除数据的操作不同,队列是“先进编译器自动分配,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。堆一般由程序员分配,若程序员不,程序结束时可能由OS回收。分配10栈typedeftypedefstruct{intdata;nodeintdata;node*next;LinkStackLinkStackS=(LinkStack)malloc(sizeof(node));S->data=0;S->next=栈的数据操作:栈的操作都是直接将数据存在栈顶,如图10.24所图10.24栈的操Push(LinkStack&S,Push(LinkStack&S,int{p=(LinkStack)malloc(sizeof(node));p->data=data;S->next=}////S为栈顶指针,data为要的数据10.2510.25Pop(Pop(LinkStack&S{LinkStackp=S-S->nextS->next=S->next->next;free(p);p=}#include<stdio.h>#include<malloc.h>voidmain(void)#include<stdio.h>#include<malloc.h>voidmain(void){nodeLinkStackS=CreateNULLStack(S//for(inti=0;i<8;{Push(S,i);printf("%d",i);}printf("\n"while(NULL!=S->next{n=Pop(S);printf("%d",n.data);}printf("\n"////}001234567654321typedeftypedefstruct{intdata;nodeLinkStackLinkStackCreateNULLStack(LinkStack{S=(LinkStack)malloc(sizeof(node));if(NULL==S){printf("Failtomallocanewreturnreturn}S->data=S->next=return}LinkStackLinkStackPush(LinkStack&S,int{if(NULL=={printf("Therenonodeinstack!");returnNULL;}LinkStackp=p=(LinkStack)malloc(sizeof(node));if(NULL==p){printf("Failtomallocanewnode.\n");returnS;}if(NULL==S-{p->next=}{p->next=S-}p->data=S->next=return}nodenodePop(LinkStack{nodetemp;temp.data=0;temp.next=NULL;if(NULL=={printf("Therenonodeinstack!");returntemp;}temp=if(S->next==NULL{printf("ThestackisNULL,can'tpop!\n");returntemp;}LinkStackp=S-//S->next=S->next->next;temp=*p;free(pp=return}动态内存申请是否成功的校验。另外就是结点指针的处理问题。如当push第一个元素时,这个元素将处于栈底直到pop,所以这个元素的指针应该是NULL,当pop操作时要检验当前栈是否为空栈,空栈是无法pop的,此时要提示错误。11typedeftypedefstruct{intdata;node*next;}node,*////typedeftypedefstruct{LinkQueueLinkQueuehead;LinkQueuetail;intsize;pQueuepQueueQ=(pQueue)malloc(sizeof(Queue));Q->head->next=Q->tail;Q->tail->next=NULL;Q->head->data=0;Q->tail->data=Q->size=10.2610.26完成了空队列的创建后,再实现队列的(push)和删除(pop)操,和删除功能的差异是链表队列以及栈这三者的根本区别下面分别介绍队列的和删除操作队列的数据操作队列的操作是直接将数据存在队首位置,如图10.27所示图10.27队列的操LinkQueuep=p=(LinkQueue)malloc(sizeof(node));p->data=data;p->next=Q->head-Q->head->next=//////每次数据都是直接插LinkQueuep=p=(LinkQueue)malloc(sizeof(node));p->data=data;p->next=Q->head-Q->head->next=//////Q- 10.2810.28pQueuep=Q-while(Q->tail!=p->next->next{p=p-}//p1=p-p->next=Q-temp=*p1;free(p1);p1pQueuep=Q-while(Q->tail!=p->next->next{p=p-}//p1=p-p->next=Q-temp=*p1;free(p1);p1=p#include<stdio.h>#include#include<stdio.h>#include<malloc.h>voidmain(void){pQueueQ=NULL;nodetemp;CreateNULLQueue(CreateNULLQueue(Qfor(inti=0;i<8;{Push(Q,i);printf("push%d",i);printf("sizeofqueueis:%d\n",Q-}whileQ->head->next!=Q->tail)//{temp=Pop(Qprintf("pop:%d",temp.data);printf("sizeofqueueis:%d\n",Q->size);}printf("\n"}pushpush0sizeofqueueis:1push1sizeofqueueis:2push2sizeofqueueis:3push3sizeofqueueispop:0sizeofqueueis:3pop:1sizeofqueueis:2pop:2sizeofqueueispop:3sizeofqueueistypedeftypedefstruct{intdata;node*next;}node,*typedeftypedefstruct{LinkQueuehead;LinkQueuetail;intsize;pQueuepQueueCreateNULLQueue(pQueue&Q{Q=(pQueue)malloc(sizeof(Queue)//if(if(NULL==Q->head{printf("FailtomalloctheheadofQueue!\n");returnNULL;}Q->head=(LinkQueue)malloc(sizeof(node));if(NULL==Q->head){printf("FailtomalloctheheadofQueue!\n");returnNULL;}Q->tail=(LinkQueue)malloc(sizeof(node));if(NULL==Q->tail){printf("FailtomalloctheheadofQueue!\n");returnNULL;}Q->head->next=Q->tail;Q->tail->next=NULL;Q->head->data=Q->tail->data=Q->size=0;returnQ;}pQueuepQueuePush(pQueue&Q,intdata{if(NULL==Q{printf("Thereisn'taqueuetopush!\n");returnNULL;}LinkQueuep=p=(LinkQueue)malloc(sizeof(node));if(NULL==p){printf("Failtomallocanewnodetopush!\n");returnQ;}p->data=p->next=Q->head->next;Q->head->next=p;returnQ;}nodenodePop(pQueue&Q{nodetemp,*p,*p1;temp.data=0;temp.next=NULL;if(NULL==Q){printf("Thereisn'taqueuetopop!\n");returntemp;}if(Q->head->next==Q-{printf("Thereisn'tanodetopop!\n");returntemp;}p=Q-while(Q->tail!=p->next->next{p=p-}//p1=p-p->next=Q-temp=*p1;free(p1);p1=preturntemp;}12栈12SS112的“先进1S2S10.2910.29两个元素进入栈21SS110.30图10.30S两次出栈栈21S110.3110.31S1nodeLinkStackS1=SS1QQ1先进nodeLinkStackS1=CreateNULLStack(CreateNULLStack(S1while(NULL!=S->next{n=Pop(S);Push(S1,n.data);}//将栈SS1while(NULL!=S1->next{n=Pop(S1);Push(S,n.data);}Pop(Pop(LinkStack&S{LinkStackp=S->next;S->next=S->next->next;free(p);p=}voidvoidmain(void{nodeLinkStackS1=CreateNULLStack(S1for(inti=0;i<8;{StackToQueuPush(S1,i);printf("%d",i);}printf("\n"while(NULL!=S1->next{n=Pop(S1);printf("%d",n.data);}printf("\n"}001234560123456 typedeftypedefstruct{intdata;nodeLinkStackLinkStackPush(LinkStack&S,int{if(NULL=={printf("Therenonodeinstack!");returnNULL;}//LinkStackp=p=(LinkStack)malloc(sizeof(node));if(NULL==p){printf("Failtomallocanewnode.\n");returnS;}if(NULL==S-{p->next=}{//LinkStackCreateNULLStack(LinkStack{S=(LinkStack)malloc(sizeof(node));if(NULL==S){printf("Failtomallocanewnode.\n");returnNULL;}S->data=S->next=return}p->next=S-}p->data=//S->next=return}nodePop(nodePop(LinkStack{nodetemp;temp.data=0;temp.next=NULL;ifNULL //{printf("Therenonodeinstack!");returntemp;}temp=if(S->next==NULL{printf("ThestackisNULL,can'tpop!\n");returntemp;}LinkStackp=S-S->next=S->next->next;temp=*p;//free(p);p=NULL;return}LinkStackLinkStackStackToQueuPush(LinkStack&S,int{nodeLinkStackS1=CreateNULLStack(S1 while(NULL!=S->next{n=Pop(SPush(Push(S1,n.data}Push(S1,datawhile(NULL!=S1->next{n=Pop(S1);Push(S,n.data);}//S1出栈入return}示清楚。如和员工之间的关系、整体与部分的关系等各种分门别类的复杂关系。这时1310.32所示。10.32typedeftypedefstruct{charstructBiTNode*lchild;structBiTNode//////构建树。从键盘输入数据,然后把这些数据树,数据输入顺序如图10.3311、2、3、#2左上方的数据#、#BiTreeCreatT(BiTree{charch=getchar();if(ch=='#'){b=}{bBiTreeCreatT(BiTree{charch=getchar();if(ch=='#'){b=}{b=(BiTree)malloc(sizeof(BiTNode));if(NULL==b){printf("overflowerr\n");returnNULL;}//b->datab->data=}return}先序遍历结果为:12345。voidvoidPreOrder(BiTree{{printf("%c",T->data);}} ////序遍历结果为:32145。voidvoidInOrder(BiTree{{printf("%c",T->data);}}////序遍历结果为:32541。voidvoidPostOrder(BiTree{{printf("%c",T-}}voidvoid{BiTreeT;intprintf("例如1#2#3#4#5#6##n");////////}例如:1#2#3#4#5#6###递归先序遍历二叉树:AB递归中序遍历二叉树:BA递归后序遍历二叉树:B14二叉树深度的计算方法:若一棵二叉树为空,则其深度为0,否则其深度等于左子树和110.333。intintdepth(BiTree{if(!T)returnintd1=depth(T->lchild);intd2=depth(T->rchild);return}intintdepth(BiTree{if(!T)returnintd1=depth(T->lchild);intd2=depth(T->rchild);return}159和如下二3 则打印出两条路径:3,63,2,4pushpath(L,T);recordpushpath(L,T);record+=T->data;if((record==sum)&&(IsLeaf(T)){printpath(L);printf("\n");}if(T->lchild!=NULL{find_path(T->lchild,sum,}if(T->rchild!=NULL{find_path(T->rchild,sum,}record-=T->data;poppath(L);return3recor

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论