经典数据结构面试题含答案.docx
- 文档编号:10158005
- 上传时间:2023-02-08
- 格式:DOCX
- 页数:20
- 大小:23.79KB
经典数据结构面试题含答案.docx
《经典数据结构面试题含答案.docx》由会员分享,可在线阅读,更多相关《经典数据结构面试题含答案.docx(20页珍藏版)》请在冰豆网上搜索。
经典数据结构面试题含答案
栈和队列共同特点是
•栈普通采用两种存储构造是
.用链表表达线性表长处是
8.在单链表中,增长头结点目是
9•循环链表重要长处是-
12.线性表顺序存储构造和线性表链式存储构造分别是
13.树是结点集合,它根结点数目是
14.在深度为5满二叉树中,叶子结点个数为
15.具备3个结点二叉树有(
16•设一棵二叉树中有3个叶子结点,有8个度为1结点,则该二叉树中总结点数为
17.已知二叉树后序遍历序列是dabec,中序遍历序列是debac,它前序適历序列是
已知一棵二叉树前序遍历和中序遍历分别为ABDEGCFH和DBGEACHF,则该二叉
树后序遍历为
19•若某二叉树前序遍历访问顺序是abdgcefh,中序遍历访问顺序是dgbaechf,则其后序
適历结点访问顺序是
20•数据库保护分为:
安全性控制、完整性控制.并发性控制和数据恢复。
在计算机中.算法是指
算法普通都可以用哪几种控制构造组合而成
.算法时间复杂度是指
5.算法空间复杂度是指
6.算法分析目是
11.数据存储构造是指
12.数据逻辑构造是指(
13.依照数据构造中齐数据元素之间先后件关系复杂限度,普通将数据构适分为
16.递归算法普通需要运用实现匚
28.非空循环单链表head尾结点(由p所指向),满足(
29.与单向链表相比,双向链表长处之一是-
34.在一棵二叉树上第8层结点数最多是
35.在深度为5满二叉树中,叶子结点个数为\
36.在深度为5满二叉树中,共有个结点
37.设一棵完全二叉树共有699个结点,则在该二叉树中叶子结点数为
阐明:
完全二叉树总结点数为N,若N为奇数,则叶子结点数为(N+l)/2:
若N为偶数,则叶子结点数为N/2。
39.已知二叉树后序遍历序列是dabec,中序遍历序列dcbac,它前序遍历序列是(cedba)
40.已知一棵二叉树前序遍历和中序遍历分别为ABDEGCFH和DBGEACHF,则该二叉树后序遍历为(DGEBHFCA)
41.若某二叉树前序遍历访问顺序是abdgeeth,中序遍历访问顺序是dgbaechf,则英后序遍历结点访问顺序是(gdbehfea)
42.串长度是(串中所含字符个数)
43•设有两个串p和q,求q在p中初次浮现位置运算称做(模式匹配)
44.N个顶点连通图中边条数至少为(N-1)
45.N个顶点强连通图边数至少有(N)
46.对长度为n线性表进行顺序查找,在最坏状况下所需要比较次数为(N)
47.最简朴互换排序办法是(冒泡排序)
4&假设线性表长度为n,则在最坏状况下,冒泡排序需要比较次数为(n(n-l)/2)
49.在待排序元素序列基本有序前提下,效率最高排序办法是(冒泡排序)
50.在最坏状况下,下列顺序办法中时间复杂度最小是(堆排序)
51.希尔排序法属于(插入类排序)
52.堆排序法属于(选取类排序)
53.在下列几种排序办法中,规世内存量最大是(归并排序)
54.lL知数据表A中每个元素距其最后位置不远,为肖约时间,应采用(直接插入排序)
55.算法基本特性是可行性、拟左性、有穷性和拥有足够情报。
一种算法普通由两种基本要素构成:
一是对数据对象运算和操作,二是算法控制构造。
1.算法复杂度重要涉及时间复杂度和空间复杂度。
2.实现算法所需存储单元多少和算法工作量大小分别称为算法空间复杂度和时间复杂
度。
3•所谓数据解决是指对数拯集合中各元素以各种方式进行运算,涉及插入、删除、査找、
更改等运算,也涉及对数据元素进行分析。
4•数据构造是指互有关于联数据元素集合。
5•数据构造分为逻借构造与存储构造,线性链表属于存储构造。
6.数据构造涉及数据逻辑构造和数据存储构造。
7.数据构造涉及数据逻辑构造、数据存储构造以及对数据操作运算。
8•数据元素之间任何关系都可以用前趋和后继关系来描述。
9•数据逻借构造有线性构造和非线性构造两大类。
10•惯用存储构造有顺序、链接、索引等存储构造。
11.顺序存储办法是把逻辑上相邻结点存储在物理位苣相邻存储单元中。
12.栈基本运算有三种:
入栈、退栈与读栈顶元素。
13.队列重要有两种基本运算:
入队运算与退队运算。
14.在实际应用中,带链栈可以用来收集让算机存储空间中所有空闲存储结点,这种带链栈称为可运用栈。
15•栈和队列普通采用存储构造是链式存储和顺序存储。
16.当线性表采用顺序存储构造实现存储时,英重要特点是逻辑构造中相邻结点在存储构造中仍相邻。
17.循环队列重要有两种基本运算:
入队运算与退队运算。
每进行一次入队运算,队尾指针就进1。
1&当循环队列非空且队尾指针等于对头指针时,阐明循环队列己满,不能进行入队运算。
这种状况称为上溢。
19•当循环队列为空时,不能进行退队运算,这种状况称为下溢。
20.在一种容量为25循环队列中,若头指针front=16.尾指针rear=9,则该循环队列中共有18个元素。
注:
肖rcarvfrom时,元素个数=总容鱼一(front-rear):
当rcar>front时,元素个数=rear—front。
5.下列关于栈论述对的是(D)
A.栈是非线性构造B.栈是一种树状构造C.栈具备先进先出特性D.栈有后进先出特性
6•链表不具备特点是(B)A.不必事先预计存储空间B.可随机访问任一元素
C.插入删除不需要移动元素D.所需空间与线性表长度成正比
10.线性表1=(al,a2,a3,……aian),下列说法对的是(D)
A.每个元素均有一种直接前件和直接后件B.线性表中至少要有一种元素
C.表中诸元素排列顺序必要是由小到大或由大到小
D.除第一种和最后一种元素外,别的每个元素均有一种且只有一种直接前件和直接后件
11.线性表若采用链式存储构造时,规左内存中可用存储单元地址(D)
A.必要是持续B.某些地址必要是持续C.—定是不持续D.持续不持续都可以
7.下列论述对的是(C)
A.算法执行效率与数据存储构造无关
B.算法空间复杂度是指算法程序中指令(或语句)条数
C.算法有穷性是指算法必要能在执行有限个环节之后终结
D.算法时间复杂度是指执行算法程序所需要时间
8•数据构造作为计算机一门学科,重要研究数据逻辑构造、对各种数据构造进行运算,
以及(数据存储构造)
9.数据构造中,与所使用汁算机无关是数据(C)
A.存储构造B.物理构造C.逻辑构造D.物理和存储构造
10.下列论述中,错误是(B)
A.数据存储构造与数据解决效率密切有关
B.数据存储构造与数据解决效率无关
C.数据存储构造在计算机中所占空间不一泄是持续
D.一种数据逻辑构造可以有各种存储构造
14.下列数据构造具备记忆功能是(C)A.队列B.循环队列C.栈D.顺序表
15.下列数据构造中,按先进后出原则组织数据是(B)
A.线性链表B.栈C.循环链表D.顺序表
17.下列关于栈论述中对的是(D)A.在栈中只能插入数据B.在栈中只能删除数据
C.栈是先进先出线性表D.栈是先进后出线性表
20.由两个栈共享一种存储空间好处是(节约存储空间,减少上溢发生机率)
21.应用程序在执行过程中,需要通过打印机输岀数据时,普通先形成一种打印作业,将英存储在硬盘中一种指泄(队列)中,当打印机空闲时,就会按先来先服务方式从中取出待打印作业进行打印。
22.下列关于队列论述中对的是(C)A.在队列中只能插入数据B.在队列中只能删除
数据C.队列是先进先岀线性表D.队列是先进后出线性表
23.下列论述中,对的是(D)A.线性链表中各元素在存储空间中位置必要是持续
B.线性链表中表头元素一定存储在其她元素前而C.线性链表中各元素在存储空间中位豊不一定是持续,但表头元素一左存储在苴她元素前而D.线性链表中各元素在存储空间中位苣不一泄是持续,且各元素存储顺序也是任意
24.下列论述中对的是(A)A.线性表是线性构造B.栈与队列是非线性构造
C.线性链表是非线性构造D.二叉树是线性构造
25.线性表L=(al,a2,a3aian),下列说法对的是(D)
A.每个元素均有一种直接前件和直接后件B.线性表中至少要有一种元素
C.表中诸元素排列顺序必要是由小到大或由大到小D.除第一种元素和最后一种元素
外,别的每个元素均有一种且只有一种直接前件和直接后件
26•线性表若采用链式存储构造时,规左内存中可用存储单元地址(持续不持续都可以)
27.链表不具备特点是(B)A.不必事先预计存储空间B.可随机访问任一元素
C.插入删除不需要移动元素D.所需空间与线性表长度成正比
30.在(D)中,只要指出表中任何一种结点位置,就可以从它出发依次访问到表中英
她所有结点。
A.线性单链表B.双向链表C.线性链表D.循环
链表
31.如下数据构造属于非线性数据构造是(C)A.队列B.线性表C.二叉树D.栈
38.设有下列二叉树,对此二叉树中序適历成果是(B)
A.ABCDEF
B.DBEAFC
C.ABDECF
D.DEBFCA
1.判断链表与否存在环型链表问题:
判断一种链表与否存在环,例如下面这个链表就存
在一种环:
例如N1->N2->N3->N4->N5->N2就是一种有环链表,环开始结点是N5这里有一种比较
简朴解法。
设立两个指针pl,p2。
每次循环pl向前走一步,p2向前走两步。
直到p2
遇到NULL指针或者两个指针相等结束循环。
如果两个指针相等则阐明存在环。
structlink
{
intdata;
link*next;
boolIsLoopdink*head)
link*pl=head,*p2=head;
if(head=NULLIIhead->next==NULL)
{
returnfalse;
}
do{
pl=pl->next;
p2=p2->next->next;
}while(p2&&p2->next&&pl!
=p2);
if(pl==p2)
returntme;
else
returnfalse;
}
2,链表反转单向链表反转是一种经常被问到一种而试题,也是一种非常基本问题。
例如一种链表是这样:
1->2->3->4->5通过反转后成为5->4->3->2->lo最容易想到办法遍历一遍链表,运用一种辅助指针,存储遍历过程中当前指针指向下一种元素,然后将当前右点元素指针反转后,运用已经存储指针往背面继续適历。
源代码如下:
structlinka{
intdata;
linka*next;
};
voidreverse(linka*&head)
if(head=NULL)
return:
linka*pre,*cur,*ne;
pre=head;
cur=head->next;
while(cur)
{
ne=cur->next;
cur->next=pre;
pre=cur;
cur=ne;
}
head->next=NULL;
head=pre;
}
尚有一种运用递归办法。
这种办法基本思想是在反转当前节点之前先调用递归函数反转后续盯点。
源代码如下。
但是这个办法有一种缺陷,就是在反转后最后一种结点会形成一种环,因此必要将函数返回节点next域宜为NULL。
由于要变化head指针,因此我用了引用。
算法源代码如下:
linka*reverse(linka*pjinka*&head)
if(p==NULLIIp->next==NULL)
head=p;
returnp;
}
else
{
linka*tmp=reverse(p->next.head);
tmp->next=p;
returnp;
}
}
3,判断两个数组中与否存在相似数字给左两个排好序数组,如何髙效得判断这两个数组中存在相似数字?
这个问题一方而想到是一种O(nlogn)算法。
就是任意挑选一种数组,遍历这个数组所有元素,遍历过程中,在列一种数组中对第一种数组中每个元素进行binarysearch。
用C++实当代码如下:
boolfindcommon(inta[],intsizel.intb[],intsize2)
{
inti;
for(i=0:
i { intstart=O.end=size2-l,mid; while(start<=end) ( mid=(start+end)/2: returntrue: elseif(a[i] end=mid-l; else start=mid+l; } } returnfalse; } 日后发既有一种O(n)算法。 由于两个数组都是排好序。 因此只要一次遍历就行了。 一方而设两个下标,分别初始化为两个数组起始地址,依次向前推动。 推动规则是比较两个数组中数字,小那个数组下标向前推动一步,直到任何一种数组下标到达数组末尾时,如果这时还没遇到相似数字,阐明数组中没有相似数字。 boolfindcommon2(inta[],intsize1,intb[],intsize2) { inti=0,j=0; while(i { if(a[i]=b|j]) returntrue; if(a[i]>b[j]) j卄; if(a[i] returnfalse; 4.最大子序列问题: 给定一整数序列Al,A2,...An(也许有负数),求Al~An—种子序列Ai~Aj,使得Ai到Aj和最大 例如: 整数序列-2,11,-4,13,-5,2,-5,-3,12,-9最大子序列和为21。 对于这个问题,最简朴也是最容易想到那就是穷举所有子序列办法。 运用三重循环,依次求岀所有子序列和然后取最大那个。 固然算法复杂度会达到0("3)。 显然这种办法不是最优,下而给出一种算法复杂度为0(n)线性算法实现,算法来源于ProgrammingPearls一书。 在给岀线性算法之前,先来看一种对穷举算法进行优化算法,它算法复杂度为0(22)。 英实这个算法只是对对穷举算法稍微做了某些修改: 苴实子序列和咱们并不需要每次都重新计算一遍。 假设Sum(i,j)是A[i]...A[j]和,那么Sum(i,j+l)=Sum(i,j)+A[j+l]o运用这一种递推,咱们就可以得到下面这个算法: intmax_sub(inta[],intsize) { intij,vjnax=a[OJ; for(i=0;i { v=0; for(j=i;j ( v=v+a[j];//Sum(i,j+l)=Sum(i,j)+Afj+1] if(v>max) max=v; returnmax; } 那如何才干达到线性复杂度呢? 这里运用动态规划思想。 先看一下源代码实现: intmax_sub2(inta[],intsize) { inti,max=04emp_sum=0; for(i=0;i { temp_sum+=a[i]; if(temp_sum>max) max=temp-sum; elseif(temp_sum<0) lcmp_sum=O: } returnmax; } 6,按单词反转字符串并不是简朴字符串反转,而是按给左字符串里单词将字符串倒转 过来,就是说字符串里而单词还是保持本来顺序,这里每个单词用空格分开。 例如: Hereis・ 通过反转后变为: isHere 如果只是简朴将所有字符串翻转话.可以遍历字符串,将第一种字符和最后一种互换,第二个和倒数第二个互换,依次循环。 英实按照单词反转话可以在第一遍遍历基本上,再遍历一遍字符串,对每一种单词再反转一次。 这样每个单词又恢复了本来顺序。 char*reverse_word(constchar*str) { intlen=strlen(slr); char*restr=newchar[len+l]; strcpy(restLstr); intij; for(i=0.j=len-l;i { chartemp=restr[i]; restr[i]=restr[j]; restr[j]=temp; } intk=0; while(k { while(restr[j]! =*&&restr[j]! =n)j卄; k=j+l; chartemp=restr[i]; restr(i]=restr[j]; restr|jl=temp: } } returnrestr; } 如果考虑空间和时间优化话,固然可以将上而代码里两个字符串互换某些改为异或实现。 例如将 chartemp=restr[i]; restr[i]=restr[j]; restr[j]=temp; 改为 restr[i]A=restr[j]; restr[j]A=restr[i]; restr[i]A=restr[j]; 7,字符串反转我没有记错话是一道MSN笔试题,网上无意中看到,拿来做了一下。 题目是这样,给泄一种字符串,一种这个字符串子串,将第一种字符串反转,但保存子串顺序不变匚例如: 输入: 第一种字符串: HThisisfishsky*sChinesesite: 子串: ”fishsky” 输岀: Hnc/nc.moc.fishsky.www//: ptth: etisesenihCsTishskysisihT 普通办法是先扫描一边第一种字符串,然后用stack把它反转,同步记录下子串浮现位宜。 然后再扫描一遍把记录下来子串再用stack反转。 我用办法是用一颯扫描数组办法。 扫描中如果发现子串,就将子串倒过来压入堆栈。 最后再将堆栈里字符弹出,这样子串又恢复了本来顺序。 源代码如下: ^include include ^include usingnamespacestd; //reversethestring*sTexceptthesubstringToken'. constchar*reverse(constchar*si,constchar*token) { assert(sl&&token); stack constchar*ptoken=token,*hcad=si>*rcar=si; while(*head! =H) while(*head! =H&&*ptoken==*hcad) ptoken++: head++; } if(*ptoken==「//containthetoken ( constchar*p; for(p=head-l;p>=rear;p-) stackl.push(*p); ptoken=token; rear=head: } else { stackl.push(*rear);head=++rear; ptoken=token; } } char*return^v=newchar[strlen(sl)+1]; inti=0; while(! stack1.emptyO) { return-v[i++]=stackl.top(); stackl.popO; rctum_v[i]=M; returnretum^v; ) intmain(intargc,char*argvf]) {cout«MThisisfishskyrsChinesesite: cout«rcverse(HThisisfishsk/sChinesesite: http: //www. fishskyH); return0; } 8,删除数组中重复数字问题: 一种动态长度可变数字序列,以数字0为结朿标志, 规左将重复数字用一种数字代替,例如: 将数组1丄1,2,2,2,2,2,7,7,1,5,5,5,0转变成1,2,7丄5,0问题比较简朴,要注意是这个数组是动态。 因此避免麻烦我还是用了STLvcctor。 ^include ^include usingnamespacestd; //removetheduplicatednumbersinanintgerarray,thearraywasendwith0; //e.g.1,1」,225,44441・0125,4,1.0 voidstaticremove_duplicated(inta[],vector { _st.push_back(a[O]); for(inti=1;_st[_st.sizc(卜1]! =0;i++) if(a[i-l]! =a[i]) _st.push_back(a[i]); } } 固然如果可以变化本来数组话,可以不用STL,仅需要指针操作就可以了。 下而这个程 序将修改本来数组内容。 voidstaticremove_duplicated2(inta[]) { if(a[O]==OIIa==NULL) return: intinsert=Lcurrent=l; while(a[current]! =O) { if(a[current]! =a[current-1]) { a[insert]=a[current]; insert++; current++; } else current++; a[insert]=O; 9,如何判断一棵二叉树与否是平衡二叉树问题: 判断一种二叉排序树与否是平衡二叉 树解决方案: 依照平衡二叉树立义,如果任意节点左右子树深度相差不超过1,那这棵树就是平衡二 叉树。 一方而编写一种计算二叉树深度函数,运用递归实现。 template staticintDcpth(BSTreeNode { if(pbs=NULL) return0; else { intId=Depth(pbs->left); intrd=Depth(pbs->right); return1+(Id>rd? ld: rd); } } 下而是运用递归判断左右子树深度与否相差1来判断与否是平衡二叉树函数: template staticboolisBalance(BSTreeNode { if(pbs=NULL) returntrue; intdis=Depth(pbs->
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 经典 数据结构 试题 答案