目录
Δ前言
- 本篇博文是“C 408—《数据结构》易错考点200题(含解析)”一文的内容补充,请在阅读本篇博文之前,先浏览一下这篇文章的前言。
- 注意事项——①点击文章侧边栏目录或者文章开头的目录可以进行跳转。②解析主要是一些解题方法和解题思路,很多解析都是up自己写得,实在简单的题目up没有写解析,请读者自己思考。
- 良工不示人以朴,up所有文章都会适时补充完善。大家如果有问题都可以在评论区进行交流或者私信up。感谢阅读!
六、图
6.1 图的基本概念
114.一个有n个顶点和n条边的无向图一定是(D)。
A.连通的 B.不连通的 C.无环的 D.有环的
Note :
假设存在一个拥有两个结点的生成树(极小连通子图),初始时只有这两个结点和一条相连的边,每当图中加入一个新的结点,若想继续保持连通的特性,新结点就必须自带一条边与图中任一结点建立连接,每加入一个新结点就对应多一条边,而这个图始终保持着连通且无环。
结论——当图的顶点数 - 边数 = 1时,刚好可以做到连通且无环(注意是可以做到,而不是一定),在此基础上,如果只是顶点数增加,则图一定不连通;如果只是边数增加,则图一定有环。所以对应于此题,选D;而连通性是不一定的。
115.若从无向图的任意顶点出发进行一次深度优先搜索即可访问所有顶点,则该图一定是(B)。
A.强连通图 B.连通图 C.有回路 D.一棵树
Note :
对于无向连通图来说,无论是进行一次广度优先搜索还是深度优先搜索,都可以访问到该连通图的所有顶点且仅访问一次。
116.以下关于图的叙述中,正确的是(C)。
A.图与树的区别在于图的边数大于等于顶点数
B.假设有图G = {V,{E}},顶点集V'⊆V,E'⊆E,则V'和{E'}构成G的子图
C.无向图的连通分量是指无向图中的极大连通子图
D.图的遍历就是从图中某一顶点出发访遍图中其余顶点
Note :
对于A,图的顶点集V一定非空,但边集E可以为空,此时图中只有顶点而没有边。∴(A)×
对于B,若E'中的边对应的顶点不在V'中,则V'和{E'}无法构成图。∴(B)×
对于D,表述存在歧义,图的遍历要求每个结点只能被访问一次,且若图非连通,则从某一顶点出发无法访问到其他全部顶点。
117.以下关于图的叙述中,正确的是(C)。
A.强连通有向图的任何顶点到其他所有顶点都有弧
B.图的任意顶点的入度等于出度
C.有向完全图一定是强连通有向图
D.有向图的边集的子集和顶点集的子集可构成原有向图的子图
Note :
对于A,注意强连通图的定义——任何一对顶点彼此之间都有路径存在,有路径存在不代表一定有直接到其他顶点的弧。
对于B,无向图任意顶点的入度等于出度,但有向图不一定满足。
对于C,正确,在有向完全图中任意两个顶点之间都存在方向相反的两条弧,则任意两个顶点之间一定存在路径。
对于D,若边集中的某条边对应的某个顶点不在对应的顶点集中,则有向图的边集的子集和顶点集的子集连图都不是,更别说子图了。(因为图的定义要求每条边两头的顶点都在顶点集V中。)
118.在有n个顶点的有向图中,每个顶点的度最大可达(D)。
A.n B.n - 1 C.2n D.2n - 2
Note :
注意题干问的是“有向图”,有向图中每个顶点的度数等于其入度与出度之和。∴最大可达2 * (n - 1) = 2n - 2。
119.若具有n个顶点的图是一个环,则它有(B)棵生成树。
A.n^2 B.n C.n-1 D.1
Note :
连通图的生成树是包含图中全部顶点的一个极小连通子图。设有n个顶点构成的环,共有n条边,去掉任意一条边就是一棵生成树,所以共有n种情况。
120.若一个具有n个顶点、e条边的无向图是一个森林,则该森林中必有(C)棵树。
A.n B.e C.n-e D.1
Note :
①“排除法”,画出一个n = 5,e = 3的森林(有两棵树,一棵树3个结点,一棵树2个结点),可知(A)(B)(D)都错,选C。
②“直接法”,回顾——在n个结点的树中有n - 1条边,即每棵树的结点数比边数多1。所以,顶点数 - 边数 = 森林中根结点的数目,即森林中树的棵树。对应于此题,n - e即为所求。
121.[2009真题] 下列关于无向连通图特性的叙述中,正确的是(A)。
Ⅰ.所有顶点的度之和为偶数
Ⅱ.边数大于顶点个数减1
Ⅲ.至少有一个顶点的度为1。
A.只有Ⅰ B.只有Ⅱ C.Ⅰ和Ⅱ D.Ⅰ和Ⅲ
Note :
对于Ⅰ,无向图的全部顶点的度的和等于边数的2倍,因为每条边和两个顶点相关联。所以无向连通图所有顶点的度之和一定为偶数。∴Ⅰ正确
对于Ⅱ,若图G是连通图,则最少有n - 1条边,所以应该是大于等于。∴Ⅱ错误
对于Ⅲ,当无向连通图的所有顶点构成一个环时,每个顶点的度为2。∴Ⅲ错误
122.[2010真题] 若无向图G = (V,E)中含有7个顶点,要保证图G在任何情况下都是连通的,则需要的边数最少是(C)。
A.6 B.15 C.16 D.21
Note :
结论——若图G是非连通图,则最多可能有C[n-1, 2]条边。对应于此题,“找临界”,将n = 7带入,可知C[6, 2] = 15,这是7个顶点的非连通图最多可能含有边的数目,如果再加一条边,15 + 1 = 16,则此时图G一定变成连通的。
123.[2011真题] 下列关于图的叙述中,正确的是(C)。
Ⅰ.回路是简单路径
Ⅱ.存储稀疏图,用邻接矩阵比邻接表更省空间
Ⅲ.若有向图中存在拓扑排序,则该图不存在回路
A.仅Ⅱ B.仅Ⅰ、Ⅱ C.仅Ⅲ D.仅Ⅰ、Ⅲ
Note :
对于Ⅰ,如果回路就是简单路径,何来的“简单回路”一说?而且,此处就算改成“简单回路”也是错的,因为简单回路和简单路径是不同的两个概念,对顶点的限制要求不同,不要混淆。
对于Ⅱ,反了。
对于Ⅲ,有回路的图不存在拓扑序列,正确。
124.[2013真题] 设图的邻接矩阵A如下所示,各顶点的度依次是(C)。
A.1,2,1,2 B.2,2,1,1 C.3,4,2,3 D.4,4,2,2
Note :
由于A是非对称矩阵,∴一定是有向图。各顶点的度是矩阵中此结点对应的行(对应出度)和列(对应入度)的非零元素之和。(第i行 和 第i列共同表示了某个结点的信息)
125.[2017真题] 已知无向图G含有16条边,其中度为4的顶点个数为3,度为3的顶点个数为4,其他顶点的度均小于3。图G所含的顶点个数至少是(B)。
A.10 B.11 C.13 D.15
Note :
利用无向图“全部顶点的度数之和 = 边数的两倍”的性质,设其他度小于3的所有结点的度数之和为x,建立等式:4*3 + 3*4 + x = 2*16,即x = 8,又因为题干问的是“顶点个数至少”,这些结点的度要么为1要么为2,可知,当这些结点的度都是2时,8 / 2 = 4,需要的结点数最少。所以总的结点数至少是3 + 4 + 4 = 11个。选B。
6.2 图的存储及基本操作
126.若图的邻接矩阵中主对角线上的元素皆为0,其余元素全为1,则可以断定该图一定(C)。
A.是无向图 B.是有向图 C.是完全图 D.不是带权图
Note :
由题设条件可知,任意两个顶点之间都有边相连,因此该图一定是完全图。
127.以下关于图的存储结构的叙述中,正确的是(B)。
A.一个图的邻接矩阵表示唯一,邻接表表示唯一
B.一个图的邻接矩阵表示唯一,邻接表表示不唯一
C.一个图的邻接矩阵表示不唯一,邻接表表示唯一
D.一个图的邻接矩阵表示不唯一,邻接表表示不唯一
Note :
在408考试中,有向图无向图的邻接矩阵表示都是唯一的;而邻接表的表示会受到读入边的顺序和边表中的插入算法的影响。
128.若邻接表中有奇数个边表结点,则(D)。
A.图中有奇数个结点 B.图中有偶数个结点 C.图为无向图 D.图为有向图
Note :
如果该图是无向图,无向图采用邻接表表示时,每条边存储两次,所以其边表结点的个数为偶数。而此题中边表结点的个数为奇数,∴一定是有向图,且图中含奇数条边。
129.n个顶点的无向图的邻接表最多有(B)个边表结点。
A.n^2 B.n(n - 1) C.n(n + 1) D.n(n - 1)/2
Note :
思路①:n个顶点的无向图最多有n(n-1)/2条边,即C[n,2],每条边在邻接表中存储两次,所以边表结点最多为n(n - 1)个。
思路②:无向图中,每个结点最多有n - 1条边,共n个结点,所以总的存储的边数 = n*(n - 1)。
130.假设有n个顶点、e条边的有向图用邻接表表示,则删除与某个顶点v相关的所有边的时间复杂度为(C)。
A.O(n) B.O(e) C.O(n + e) D.O(ne)
Note :
有向图,删除某个顶点v相关的所有边包含两种情况——
①删除v的出边:只需遍历v的顶点表结点和其指向的边表,以删除顶点v以及挂在后面的单链表,由于v的出边最多是n-1,所以删除出边的时间复杂度为O(n)。
②删除v的入边:需要遍历所有边表,即扫描剩余的全部顶点和挂在它们后面的单链表,以删除所有v的入边,时间复杂度为O(n + e)。
所以,总的时间复杂度为T(n) = O(n) + O(n + e) = O(n + e)。
6.3 图的遍历
131.判断有向图中是否存在回路,除可以利用拓扑排序外,还可以利用(C)。
A.求关键路径的方法 B.求最短路径的Dijkstra算法
C.深度优先遍历算法 D.广度优先遍历算法
Note :
对于A,回顾——关键路径的概念:在AOE网(用有向边表示活动的网络)中,从开始顶点到结束顶点的所有路径中,具有最大路径长度的路径称为关键路径,而把关键路径上的活动称为关键活动。∴求关键路径的前提是有向无环图(Directed Acyclic Graph, 简称DAG)。PS : A选项具有争议性,但由于是单选题,所以直接选C就完了。
对于B,Dijkstra算法可以求解有回路的带权图的最短路径,也可以求任意两个顶点的最短路径,不适合求带负权值的最短路径,可知有没有环对Dijkstra算法没什么影响。
对于C,如果在遍历过程中下一个将要访问的结点已经在栈中,则说明图中存在环路。
对于D,广度优先遍历算法不能检测环的存在。
132.使用DFS算法递归地遍历一个无环有向图,并在退出递归时输出相应顶点,这样得到的顶点序列是(A)。
A.逆拓扑排序 B.拓扑排序 C.无序的 D.都不是
Note :
此题可用排除法,可假设图G1为A->B->C,排除BCD。或者,更一般地,可假设图G2,顶点A指向B和D,而B和D顶点又同时指向了C,那么图G2的拓扑排序是ABDC或ADBC,而根据题设条件得到的序列是CBDA或CDBA,显然是逆拓扑排序。
注意DFS算法的定义,只要当前遍历的结点还有其他邻接顶点未被访问过,就继续向下访问,直到该顶点没有未被访问过的邻接顶点,才将该顶点退栈。
133.设无向图G = (V,E)和G' = (V',E'),若G'是G的生成树,则下列说法中错误的是(B)。
A.G'为图G的子图 B.G'为G的连通分量
C.G'为G的极小连通子图且V' = V D.G'是G的一个无环子图
Note :
回顾几个概念:
①子图:设有图G = (V,E),若V'是V的子集,E'是E的子集,并且V'和E'可以构成图G',则称G'是G的子图。
②生成子图:若在①的条件下,满足V' = V,则称G'为G的生成子图。
③连通分量:无向图中的极大连通子图。
④生成树:连通图的生成树是包含图中全部顶点的一个极小连通子图。
对应于此题,生成树是极小连通子图,所以B错。
134.[2013真题] 若对如下无向图进行遍历,则下列选项中,不是广度优先遍历序列的是(D)。
A.h,c,a,b,d,e,g,f B.e,a,f,g,b,h,c,d
C.d,b,c,a,h,e,f,g D.a,b,c,d,h,e,f,g
135.[2015真题] 设有向图G = (V,E),顶点集V = {V0, V1, V2, V3},边集E = {<v0,v1>, <v0,v2>, <v0,v3>, <v1,v3>}。若从顶点V0开始对图进行深度优先遍历,则可能得到的不同遍历序列个数是(D)。
A.2 B.3 C.4 D.5
136.[2016真题] 下列选项中,不是下图深度优先搜索序列的是(D)。
A.V1, V5, V4, V3, V2 B.V1, V3, V2, V5, V4
C.V1, V2, V5, V4, V3 D.V1, V2, V3, V4, V5
6.4 图的应用
137.以下叙述中,正确的是(A)。
A.最短路径一定是简单路径
B.Dijkstra算法不适合求有回路的带权图的最短路径
C.Dijkstra算法不适合求任意两个顶点的最短路径
D.Floyd算法求两个顶点的最短路径时,path(k-1)一定是path(k)的子集
Note :
①Dijkstra算法适合求解有回路的带权图的最短路径,也可以求任意两个顶点的最短路径(轮流将每个顶点作为源点,并且在所有边权值均非负时,运行一次Dijkstra算法),但不适合求带负权值的最短路径问题。
②Floyd算法求两个顶点的最短路径,当最短路径发生更改时,path(k-1)就不是path(k)的子集。
138.下面的(A)方法可以判断出一个有向图是否有环(回路)。
Ⅰ.深度优先遍历 Ⅱ.拓扑排序 Ⅲ.求最短路径 Ⅳ.求关键路径
A.Ⅰ、Ⅱ、Ⅳ B.Ⅰ、Ⅲ、Ⅳ C.Ⅰ、Ⅱ、Ⅲ D.全部可以
Note :
注意对比131题。这题是多选题,可知Ⅰ和Ⅱ一定对,而Ⅲ一定错,所以只能选A了。(王道书上的什么破题)
139.若一个有向图的顶点不能排在一个拓扑序列中,则可判定该有向图(D)。
A.是一个有根的有向图 B.是一个强连通图
C.含有多个入度为0的结点 D.含有顶点数目大于1的强连通分量
Note :
对于A,有没有根和有没有环无关。
对于B,注意要区分“完全有向图”和“强连通图”的区别,前者是任意两个顶点之间必须有方向相反的两条弧,后者是任意两个顶点之间相互都存在路径。题干只是说了这是一个有环图,并不能说明任意两个顶点之间就存在路径,因为这个环可能只是整个图的一小部分。
对于C,扯蛋,没关系。
对于D,强连通分量——有向图中的极大强连通子图;因为顶点数目大于1,所以显然存在环。
140.以下关于拓扑排序的说法中,错误的是(D)。
Ⅰ.若某有向图存在环路,则该有向图一定不存在拓扑排序
Ⅱ.在拓扑排序算法中为暂存入度为0的顶点,可以使用栈,也可以使用队列
Ⅲ.若有向图的拓扑序列唯一,则图中每个顶点的入度和出度最多为1
A.Ⅰ、Ⅲ B.Ⅱ、Ⅲ C.Ⅱ D.Ⅲ
Note :
对于Ⅰ,根据拓扑排序的定义和步骤可知,正确。(自己翻翻课本啊,竟成或者王道)
对于Ⅱ,压栈或者入队的结点都是入度为0的结点,即它们之间没有关系,哪个点都可以先进行遍历,根据拓扑排序的定义和步骤可知,正确。
对于Ⅲ,做一遍真题,真题里面都有这样的反例。
141.若一个有向图的顶点不能排成一个拓扑序列,则判定该有向图(D)。
A.含有多个出度为0的顶点 B.是个强连通图
C.含有多个入度为0的顶点 D.含有顶点数大于1的强连通分量
Note :
和139题问的一样,属于是脱裤子放屁,唯一不同的地方在A选项,注意,当整个图就是一个环的时候,满足题干条件,但图中不含有任何出度为0的顶点。
142.下列关于图的说法中,正确的是(C)。
Ⅰ.有向图中顶点V的度等于其邻接矩阵中第V行中1的个数
Ⅱ.无向图的邻接矩阵一定是对称矩阵,有向图的邻接矩阵一定是非对称矩阵
Ⅲ.在图G的最小生成树G1中,某条边的权值可能会超过未选边的权值
Ⅳ.若有向无环图的拓扑序列唯一,则可以唯一确定该图
Note :
Ⅰ和Ⅱ显然错,Ⅲ肯定对,没啥争议。重点在Ⅳ,这句话的说法和140题的Ⅲ很像,呵,我们马上就会遇到一个反例,它就在真题中。
143.[2010真题] 对下图进行拓扑排序,可得不同拓扑序列的个数是(B)。
A.4 B.3 C.2 D.1
144.[2012真题] 下列关于最小生成树的叙述中,正确的是(A)。
Ⅰ.最小生成树的代价唯一
Ⅱ.所有权值最小的边一定会出现在所有的最小生成树中
Ⅲ.使用Prim算法从不同顶点开始得到的最小生成树一定相同
Ⅳ.使用Prim算法和Kruskal算法得到的最小生成树总不相同
A.仅Ⅰ B.仅Ⅱ C.仅Ⅰ、Ⅲ D.仅Ⅱ、Ⅳ
Note :
对于Ⅱ,若带权连通无向图G本身是一个环,且每条边的权值都相同,则撤去该环中的任意一条边,都可以生成图G的最小生成树,显然,被撤去的那条边同样是权值最小的边,但它没有出现在最小生成树中。
对于Ⅲ,根据普里姆算法的定义可知,最后得到的最小生成树很大程度上取决于初始顶点的选择,因此,“一定相同”肯定不对。
对于Ⅳ,“总不相同”,扯淡。若图G是缺少一条边的一个环,则它的最小生成树就是它本身,此时使用Prim算法和Kruskal算法得到的最小生成树相同。(PS : 注意,最小生成树的定义是基于边的权重之和最小的条件,即最小生成树中没有“根结点”的概念。)
145.[2012真题] 对下图所示的有向带权图,若采用Dijkstra算法求从源点a到其他各顶点的最短路径,则得到的第一条最短路径的目标顶点是b,第二条最短路径的目标顶点是c,后续得到的其余各最短路径的目标顶点依次是(C)。
A.d,e,f B.e,d,f C.f,d,e D.f,e,d
146.[2013真题] 下列AOE网表示一项包含8个活动的工程。通过同时加快若干活动的进度可以缩短整个工程的工期。下列选项中,加快其进度就可以缩短工程工期的是(C)。
A.c 和 e B.d 和 c C.f 和 d D.f 和 h
Note :
一定要注意“眼力”,看仔细喽!此题中,图中一共有三条关键路径(三条“带权路径长度之和相同的”路径),分别是b-->f-->h,b-->d-->e-->h,b-->d-->c-->g,前两条很好找,第三条容易漏掉,注意此处e + h = c + g。显然,缩短f 和 d,可以同时缩短三条关键路径的带权路径长度之和。
147.[2012真题] 若用邻接矩阵存储有向图,矩阵中主对角线以下的元素均为零,则关于该图拓扑序列的结论是(C)。
A.存在,且唯一 B.存在,且不唯一
C.存在,可能不唯一 D.无法确定是否存在
Note :
对角线以下的元素均为零,表明只有从顶点i 到顶点j (i < j)可能右边,而相反方向一定无边,即有该向图是一个无环图,因此一定存在拓扑序列。但拓扑序列不一定是唯一的,如果题干中说“对角线以上的元素全为1,对角线以下的元素全为0,则拓扑序列不但存在且唯一。
148.[2014真题] 对下图所示的有向图进行拓扑排序,得到的拓扑序列可能是(D)。
A.3,1,2,4,5,6 B.3,1,2,4,6,5 C.3,1,4,2,5,6 D.3,1,4,2,6,5
149.[2015真题] 求下面的带权图的最小(代价)生成树时,可能是Kruskal算法第2次选中但不是Prim算法(从V4开始)第2次选中的边是(C)。
A.(V1,V3) B.(V1,V4) C.(V2,V3) D.(V3,V4)
150.[2016真题] 使用Dijkstra算法求下图中从顶点1到其他各顶点的最短路径,依次得到的各最短路径的目标顶点是(B)。
A.5,2,3,4,6 B.5,2,3,6,4 C.5,2,4,3,6 D.5,2,6,3,4
Note :
依旧没啥好说的,看仔细,考得就是你的“眼力”!
151.[2016真题] 若对n个顶点、e条弧的有向图采用邻接表存储,则拓扑排序算法的时间复杂度是(B)。
A.O(n) B.O(n + e) C.O(n^2) D.O(ne)
Note :
回顾——图的遍历:不论是BFS算法还是DFS算法,采用邻接矩阵表示时,总的时间复杂度为O(|V|^2);采用邻接表表示时,总的时间复杂度为O(|V| + |E|)。在生成拓扑序列的过程中,通常依赖图的遍历算法来实现。
152.[2018真题] 下列选项中,不是如下有向图的拓扑序列的是(D)。
A.1,5,2,3,6,4 B.5,1,2,6,3,4 C.5,1,2,3,6,4 D.5,2,1,6,3,4
153.[2019真题] 下图所示的AOE网表示一项包含8个活动的工程。活动d的最早开始时间和最迟开始时间分别是(C)。
A.3 和 7 B.12 和 12 C.12 和 14 D.15 和 15
Note :
活动d的最早开始时间:a和b都执行完成后(注意b开始的前提是c已经完成),所以最早开始时间是c + b = 8 + 4 = 12。
活动d的最迟开始时间:关键路径的长度是27(有两条关键路径),只要不影响关键路径的长度(保证后续任务可以按时完成),那么活动d就可以拖一拖再开始执行,27 - (7 + 6) = 14,所以最迟开始时间是14。
154.[2019真题] 用有向无环图描述表达式(x + y)((x + y)/x),需要的顶点个数至少是(A)。
A.5 B.6 C.8 D.9
Note :
注意,运算符号也可以合并。
155.[2020真题] 已知无向图G如下所示,使用克鲁斯卡尔(Kruskal)算法求图G的最小生成树,加到最小生成树中的边依次是(A)。
A.(b,f), (b,d), (a,e), (c,e), (b,e)
B.(b,f), (b,d), (b,e), (a,e), (c,e)
C.(a,e), (b,e), (c,e), (b,d), (b,f)
D.(a,e), (c,e), (b,e), (b,f), (b,d)
156.[2020真题] 修改递归方式实现的图的深度优先搜索(DFS)算法,将输出(访问)顶点信息的语句移到退出递归前(即执行输出语句后立刻退出递归)。采用修改后的算法遍历有向无环图G,若输出结果中包含G中的全部顶点,则输出的顶点序列是G的(B)。
A.拓扑有序序列 B.逆拓扑有序序列
C.广度优先搜索序列 D.深度优先搜索序列
157.[2020真题] 若使用AOE网估算工程进度,则下列叙述中正确的是(B)。
A.关键路径是从源点到汇点边数最多的一条路径
B.关键路径是从源点到汇点路径长度最长的路径
C.增加任一关键活动的时间不会延长工程的工期
D.缩短任一关键活动的时间将会缩短工程的工期
158.[2021真题] 给定如下有向图,该图的拓扑有序序列的个数是(A)。
A.1 B.2 C.3 D.4
Note :
注意到A-->B-->C-->D-->E-->F都有弧存在,所以该有向图的拓扑序列一定唯一。回答上面140题的Ⅲ,此时存在入度和出度大于1的顶点。并且,该拓扑序列对应的图不是唯一的,比方说再加一条B-->E的弧,拓扑序列不变。
159.[2021真题] 使用Dijkstra算法求下图中从顶点1到其余各顶点的最短路径,将当前找到的从顶点1到顶点2,3,4,5的最短路径的长度保存在dist中,求出第二条最短路径后,dist中的内容更新为(C)。
A.26,3,14,6 B.25,3,14,6 C.21,3,14,6 D.15,3,14,6
七、查找
7.2 顺序查找和折半查找
160.由n个数据元素组成的两个表:一个递增有序,一个无序。采用顺序查找算法,对有序表从头开始查找,发现当前元素已不小于待查元素时,停止查找;确定查找不成功,已知查找任一元素的概率是相同的,则在两种表中成功查找(B)。
A.平均时间后者小 B.平均时间两者相同
C.平均时间前者小 D.无法确定
Note :
注意题干问的是“成功查找”,在顺序查找中,有序线性表和一般线性表的查找成功的平均查找长度是一样的,ASL = (n+1) / 2;不同的是“查找失败”的情况,无序表中,查找失败的平均查找长度ASL = n + 1,而有序表中,查找失败的平均查找长度ASL = n/2 + n/(n+1)。
161.折半查找和二叉排序树的时间性能(B)。
A.相同 B.有时不相同 C.完全不同 D.无法比较
Note :
折半查找的判定树是一棵平衡二叉树,一般情况比二叉排序树的查找效率更高。
162.在有11个元素的有序表A[1,2,...,11]中进行折半查找(⌊(low + high) / 2⌋),查找元素A[11]时,被比较的元素的下标依次是(B)。
A.6,8,10,11 B.6,9,10,11 C.6,7,9,11 D.6,8,9,11
Note :
没啥好说的,注意折半查找每次和mid比较完之后,要移动low或者是high的指针;如果要查找的元素还在前半部分,令high = mid - 1;如果要查找的元素还在后半部分,令low = mid + 1;移动指针后再重新计算mid。
163.设顺序存储的某线性表共有123个元素,按分块查找的要求等分为3块。若对索引表采用顺序查找法来确定子块,且在确定的子块中也采用顺序查找法,则在等概率情况下,分块查找成功的平均查找长度为(B)。
A.21 B.23 C.41 D.62
Note :
每块中元素的个数为123 / 3 = 41,此题求ASL有两种方法,可以分别算出索引查找和块内查找的ASL,然后相加,即(3+1)/2 + (41+1)/2 = 2 + 21 = 23;也可以直接套公式ASL = (s^2 + 2s + n) / 2s = 23。(s表示每块中的记录数)
164.为提高查找效率,对有65025个元素的有序顺序表建立索引顺序结构,在最好情况下查找到表中已有元素最多需要执行(C)次关键字比较。
A.10 B.14 C.16 D.21
Note :
“索引顺序结构”即分块查找,最好情况下,每个分块中的记录数为√65025 = 255,且索引查找和块内查找都使用折半查找,又因为折半查找法查找到给定值的比较次数最多不会超过树的高度,所以“在最好情况下的最多比较次数” = ⌈log[2](255 + 1)⌉ + ⌈log[2](255 + 1)⌉ = 8 + 8 = 16。
165.[2010真题] 已知一个长度为16的顺序表L,其元素按关键字有序排列,若采用折半查找法查找一个L中不存在的元素,则关键字的比较次数最多是(B)。
A.4 B.5 C.6 D.7
Note :
⌈log[2](16 + 1)⌉ = 5。PS : 亦可自己画个图试试,最多是5,最少比较次数是4。
166.[2015真题] 下列选项中,不能构成折半查找中关键字比较序列的是(A)。
A.500,200,450,180 B.500,450,200,180
C.180,500,200,450 D.180,200,500,450
Note :
联系折半查找的判定树是如何构建的。(二叉排序树且是一棵平衡二叉树)
167.[2016真题] 在有n(n>1000)个元素的升序数组A中查找关键字x。查找算法的伪代码如下所示。
k = 0;
while (k < n 且 A[k] < x) k = k + 3;
if (k < n 且 A[k] == x) 查找成功;
else if (k - 1 < n 且 A[k-1] == x) 查找成功;
else if (k - 2 < n 且 A[k-2] == x) 查找成功;
else 查找失败;
本算法与折半查找算法相比,有可能具有更少比较次数的情形是(B)。
A.当x不在数组中 B.当x接近数组开头处
C.当x接近数组结尾处 D.当x位于数组中间位置
Note :
该题本质上类似于顺序查找。
168.[2017真题] 下列二叉树中,可能成为折半查找判定树(不含外部结点) 的是(A)。
Note :
对于顺序表中含有偶数个元素的情况,比如说顺序表中存在1,2,3,4,5,6,7,8这八个元素,采用折半查找法时,mid指向表中间位置的元素,则理论上mid既可以选4(向下取整),又可以选5(向上取整),则既可以选择中间分割线左边的元素,又可以选择中间分割线右边的元素。但是,一棵折半查找判断树中,应该只采用其中一种选择mid的方式,不能混用。因此排除BCD。PS : 排除时,可以数一下图中共几个元素,假设图中共n个元素,可以将1~n带入验证,可以很快排除。
7.3 树型查找
169.构造一棵具有n个结点的二叉排序树时,最理想情况下的深度为(D)。
A.n/2 B.n C.⌊log[2](n+1)⌋ D.⌈log[2](n+1)⌉
Note :
二叉排序树的最理想情况不是平衡二叉树,而是完全二叉树,具有n(n>0)个结点的完全二叉树的高度为⌈log[2](n+1)⌉,看清楚是向上取整。
170.含有20个结点的平衡二叉树的最大深度为(C)。
A.4 B.5 C.6 D.7
Note :
给定具体结点数目,要求最大深度,即每层最少结点,想到平衡二叉树的递推公式——n(h)表示深度为h的平衡二叉树中含有的最少结点数,有n0=0, n1=1, n2=2,且n(h) = n(h-1) + n(h-2) + 1。由该递推公式可知,n(5) = 12,n(6) = 20。
171.[2009真题] 下列二叉排序树中,满足平衡二叉树定义的是(B)。
172.[2010真题] 在下图所示的平衡二叉树中插入关键字中插入关键字48后得到一棵新平衡二叉树,在新平衡二叉树中,关键字37所在结点的左、右子结点中保存的关键字分别是(C)。
A.13, 48 B.24, 48 C.24, 53 D.24, 90
173.[2011真题] 对下列关键字序列,不可能构成某二叉排序树中一条查找路径的是(A)。
A.95,22,91,24,94,71 B.92,20,91,34,88,35
C.21,89,77,29,36,38 D.12,25,71,68,33,34
Note :
这种题有一个小技巧——注意相邻间隔一位的元素(比方说A中的91 24 94),如果中间这个元素比左右两边的元素都小,而且右边的元素比左边的元素大,那它肯定不能构成二叉排序树的查找路径。原因也很简单,你中间元素比左边元素小,说明从中间元素开始的所有元素都在左边元素的左子树上,包括右边元素,可是你右边元素比左边元素还大了,这不是道反天罡么。
174.[2012真题] 若平衡二叉树的高度为6,且所有非叶子结点的平衡因子均为1,则该平衡二叉树的结点总数为(B)。
A.12 B.20 C.32 D.33
Note :
此题要用到平衡二叉树结点总数的递推公式——n(h) = n(h-1) + n(h-2) + 1。怎么理解这个公式呢?n(h)表示深度为h的平衡二叉树的结点总数,那么,它是不是就等于左子树的结点数 + 右子树的结点数 + 根结点(也就是最后那个1)。当我们从h = 0开始画图模拟,依次递推时,发现通过这个递推公式得到的平衡二叉树恰好就满足题设题设条件——所有非叶子结点的平衡因子均为1。
175.[2013真题] 在任意一棵非空二叉排序树T1中,删除某结点v之后形成二叉排序树T2,再将v插入T2形成二叉排序树T3。下列关于T1与T3的叙述中,正确的是(C)。
I.若v是T1的叶结点,则T1与T3不同
II.若v是T1的叶结点,则T1与T3相同
III.若v不是T1的叶结点,则T1与T3不同
IV.若v不是T1的叶结点,则T1与T3相同
A.仅Ⅰ、Ⅲ B.仅Ⅰ、Ⅳ C.仅Ⅱ、Ⅲ D.仅Ⅱ、Ⅳ
176.[2013真题] 若将关键字1,2,3,4,5,6,7依次插入初始为空的平衡二叉树T,则T中平衡因子为0的分支结点的个数是(D)。
A.0 B.1 C.2 D.3
177.[2015真题] 现有一棵无重复关键字的平衡二叉树(AVL),对其进行中序遍历可得到一个降序序列。下列关于该平衡二叉树的叙述中,正确的是(D)。
A.根结点的度一定为2 B.树中最小元素一定是叶结点
C.最后插入的元素一定是叶结点 D.树中最大元素一定是无左子树
Note :
“中序遍历得到一个降序序列”,说明该平衡二叉树是和正常的平衡二叉树反着来的,即左右颠倒。根据中序遍历“左根右”的特性,树中最大元素一定是最左下的元素,所以D正确。ABC都可以利用平衡二叉树“自平衡”的特性,画图排除,很简单这里就不画了。
178.[2018真题] 已知二叉排序树如下图所示,元素之间应满足的大小关系是(C)。
A.x1 < x2 < x5 B.x1 < x4 < x5 C.x3 < x5 < x4 D.x4 < x3 < x5
Note :
二叉排序树默认“左根右”,即中序遍历得到一个递增的序列,根据x4,x5的位置关系,可知x5 < x4,所以排除BD,根据x2的位置关系可知x2是图中最大的元素,所以排除A,选C。
179.[2019真题] 在任意一棵非空平衡二叉树(AVL树)T1中,删除某结点v之后形成平衡二叉树T2,再将v插入T2形成平衡二叉树T3。下列关于T1与T3的叙述中,正确的是(A)。
Ⅰ.若v是T1的叶结点,则T1与T3可能不相同
Ⅱ.若v不是T1的叶结点,则T1与T3一定不相同
Ⅲ.若v不是T1的叶结点,则T1与T3一定相同
A.仅Ⅰ B.仅Ⅱ C.仅Ⅰ、Ⅱ D.仅Ⅰ、Ⅲ
Note :
由于平衡二叉树“自平衡”的特性,无论删除的是叶子结点还是非叶子结点,都有可能导致T1和T3相同或者是不同。
180.[2020真题] 下列给定的关键字输入序列中,不能生成右边二叉排序树的是(B)。
A.4, 5, 2, 1, 3 B.4, 5, 1, 2, 3
C.4, 2, 5, 3, 1 D.4, 2, 1, 3, 5
Note :
注意题干问的是“二叉排序树”,二叉排序树没有自平衡的特性,根结点“左2右5”,所以4遇到的第一个比它小的元素一定是2,4遇到的第一个比它大的元素一定是5,由此秒选B。
181.[2021真题] 给定平衡二叉树如下图所示,插入关键字23后,根中的关键字是(D)。
A.16 B.20 C.23 D.25
Note :
PS : "LL", "RR"转儿子;"LR", "RL"转孙子。(儿子和孙子是相对于最小不平衡子树的根结点而言的。)
7.4 B树和B+树
182.下图是一棵(A)。
A.4阶B树 B.4阶B+树 C.3阶B树 D.3阶B+树
Note :
显然这是一棵B树(根结点2个关键字对应有3棵子树),注意到根结点的第二个孩子结点有3个元素,根据B树的定义,m阶B树每个结点的关键字个数最多为m - 1,所以这一定不能是3阶B树,所以选A。
183.下列关于m阶B树的说法中,错误的是(C)。
A.根结点至多有m棵子树
B.所有叶结点都在同一层次上
C.非叶结点至少有m/2(m为偶数)或(m+1)/2(m为奇数)棵子树
D.根结点中的数据是有序的
Note :
对于C选项,应该强调是非根的非叶结点,因为如果是根结点的话,B树的根结点含有的关键字个数最少是1,对应最少含有2棵子树。
184.具有n个关键字的m阶B树,应有(A)个叶结点。
A.n+1 B.n-1 C.mn D.nm/2
Note :
B树的叶子结点对应查找失败的情况,对有n个关键字的查找集合进行查找,失败可能性有n+1种。
PS : 亦可用“排除法”,画一棵三个结点的B树(1-2),使n = 5,m=2,可知BCD×。
185.含有n个非叶结点的m阶B树中至少包含(D)个关键字。
A.n(m+1) B.n C.n(⌈m/2⌉-1) D.(n-1)(⌈m/2⌉-1) + 1
Note :
n个非叶结点,其中又分为 1 个根结点和 n-1 个非根的非叶结点;题干问的是“至少”,B树的根结点最少包含一个关键字,除去根结点外,B树的每个非叶结点都至少含有⌈m/2⌉-1个关键字。所以整棵B树至少包含(n-1)(⌈m/2⌉-1) + 1个关键字。
186.下列关于B树和B+树的叙述中,不正确的是(A)。
A.B树和B+树都能有效地支持顺序查找
B.B树和B+树都能有效地支持随机查找
C.B树和B+树都是平衡的多叉树
D.B树和B+树都可以用于文件索引结构
Note :
对于AB,B树仅支持随即查找;而B+树支持顺序查找和随机查找,这是因为B+树的所有非叶结点仅起索引作用,所有叶结点中已经包含了全部的关键字信息,且叶结点本身依照关键字大小从小到大顺序链接,因此可以支持顺序查找。
PS : B树和B+树中,结点所含关键字个数的区别——
B树:根结点(1 ≤ n ≤ m-1);其他非叶结点(⌈m/2⌉-1 ≤ n ≤ m-1)。
B+树:根结点(2 ≤ n ≤ m);其他非叶结点(⌈m/2⌉ ≤ n ≤ m)。
187.[2009真题] 下列叙述中,不符合m阶B树定义要求的是(D)。
A.根结点至多有m棵子树 B.所有叶结点都在同一层上
C.各结点内关键字均升序或降序排列 D.叶结点之间通过指针链接
Note :
显然,D说的是B+树,我们心里还是要有点B树的。
188.[2012真题] 已知一棵3阶B树,如下图所示。删除关键字78得到一棵新B树,其最右叶结点中的关键字是(D)。
A.60 B.60,62 C.62,65 D.65
Note :
B树在删除一个关键字时,如果出现“兄弟够借”的情况,会涉及到三个关键字——①被删除的关键字本身;②③被删除的关键字的“后继”和“后继的后继”,或“前驱”和“前驱的前驱”。对应于此题,删除78符合“兄弟够借”的情况,78的“前驱”和“前驱的前驱”分别是65和62,此时,只需要将这三个关键字“转一圈”,即78删去,65替代78, 62替代65。如下图所示 :
189.[2013真题] 在一棵高度为2的5阶B树中,所含关键字的个数至少是(A)。
A.5 B.7 C.8 D.14
Note :
设m阶B树的高度为h,h满足——log[m](n+1) ≤ h ≤ log⌈m/2⌉((n+1)/2) + 1。(注意m/2的向上取整符号"⌈⌉")。根据已知的高度h和阶数m,就可以反推出B树中关键字个数的最大和最小情况。(当然,反推的时候,公式要反着用)。
190.[2014真题] 在一棵有15个关键字的4阶B树中,含关键字的结点个数最多是(D)。
A.5 B.6 C.10 D.15
Note :
注意与上一题不同,此题问的是“结点”的个数,关键字的总数确定,要想结点个数最多,就要设法让每个结点所含的关键字个数最少,又因为⌈4/2⌉ - 1 = 1,所以每个结点都只含1个关键字(恰好根结点最少也是1个关键字),而1个关键字对应有2棵子树,所以总的结点数 = 1 + 2 + 4 + 8 = 15。
191.[2016真题] B+树不同于B树的特点之一是(A)。
A.能支持顺序查找 B.结点中含有关键字
C.根结点至少有两个分支 D.所有叶结点都在同一层上
Note :
对于A,解析见上面186题。
192.[2017真题] 下列应用中,适合使用B+树的是(B)。
A.编译器中的词法分析 B.关系数据库系统中的索引
C.网络中的路由表快速查找 D.操作系统的磁盘空闲块管理
Note :
对于A,编译器中的词法分析使用有穷自动机和语法树。
对于B,B+树是应数据库所需而出现的一种B树的变形,前者比后者更加适用于实际应用中的操作系统的文件索引和数据库索引,因为使用B+树的磁盘读写代价更低,查询效率更加稳定。
对于C,网络中的路由表快速查找主要靠高速缓存、路由表压缩技术和快速查找算法。
对于D,系统一般使用空闲空间链表来管理磁盘空闲块。
193.[2018真题] 高度为5的3阶B树含有的关键字个数至少是(B)。
A.15 B.31 C.62 D.242
Note :
同189题,使用公式“log[m](n+1) ≤ h ≤ log⌈m/2⌉((n+1)/2) + 1”反推即可。
194.[2020真题] 依次将关键字5,6,9,13,8,2,12,15插入初始为空的4阶B树后,根结点中包含的关键字是(B)。
A.8 B.6,9 C.8,13 D.9,12
Note :
4阶B树,则每个结点最多允许有3个关键字。画个图很简单的。
195.[2021真题] 在一棵高度为3的3阶B树中,根为第1层,若第2层中有4个关键字,则该树的结点数最多是(A)。
A.11 B.10 C.9 D.8
Note :
3阶B树,则每个结点最多允许有2个关键字。第2层限定了关键字总数,又想要树中的结点数最多,当然要尽可能地使每个结点所含的关键字最少(注意这里说的是第2层),由于根结点最多有2个关键字,所以第2层最多会出现(2-1-1)这三个结点,对应的第3层有七个结点,所以结点总数最多是1 + 3 + 7 = 11。
7.5 散列表
196.假定有K个关键字互为同义词,若用线性探测法把这K个关键字填入散列表,至少要进行(D)次探测。
A.K-1 B.K C.K+1 D.K(K+1)/2
Note :
只有第一个关键字探测不会发生冲突,所以只需探测1次。第二个关键字需要探测2次,第三个关键字需要探测3次......第K个关键字需要探测K次,所以总的探测次数 = 1 + 2 + 3 + ... + K = K(K+1)/2。
197.[2011真题] 为提高散列表的查找效率,可以采取的正确措施是(D)。
Ⅰ.增大装填(载)因子
Ⅱ.设计冲突(碰撞)少的散列函数
Ⅲ.处理冲突(碰撞)时避免产生聚集(堆积)现象
A.仅Ⅰ B.仅Ⅱ C.仅Ⅰ、Ⅱ D.仅Ⅱ、Ⅲ
Note :
散列表的查找效率取决于三个因素:①散列函数、②处理冲突的方法、③装填因子。
可知Ⅱ和Ⅲ一定对。对于装填因子α,α越大,表示装填的记录越“满”,发生冲突的可能性越大,反之发生冲突的可能性越小。所以Ⅰ错,应该是减小装填因子。
198.[2014真题] 用哈希(散列)方法处理冲突(碰撞)时可能出现堆积(聚集)现象,下列选项中,会受堆积现象直接影响的是(D)。
A.存储效率 B.散列函数 C.装填因子 D.平均查找长度
Note :
“堆积”现象对存储效率,散列函数和装填因子均不会有影响,但会增大平均查找长度。
199.[2018真题] 现有长度为7、初始为空的散列表HT,散列函数H(k) = k%7,用线性探测再散列法解决冲突。将关键字22,43,15依次插入HT后,查找成功的平均查找长度是(C)。
A.1.5 B.1.6 C.2 D.3
200.[2019真题] 现有长度为11且初始为空的散列表HT,散列函数是H(key) = key%7,采用线性探测(线性探测再散列)法解决冲突。将关键字序列87,40,30,6,11,22,98,20依次插入HT后,HT查找失败的平均查找长度是(C)。
A.4 B.5.25 C.6 D.6.29
Note :
此题的思路突破口在于——由于散列函数为key%7,所以无论查找的是存在于表中的元素还是不存在于表中的元素,H(key)的结果只能等于0~6中的一个。而此题给出的关键字序列恰好填入了散列表的0~6以及7这八个位置。当某个不存在于表中的元素经过散列函数映射到0下标时,需要一直比较到8下标才能知道表中的确不存在当前查找的元素,而从0下标比较到8下标,共比较了9次;对应的,当映射到1下标时,需要比较8次(从1小标比较到8下标),以此类推。由于H(key)的结果只能等于0~6中的一个(共7种结果),所以平均查找长度 = (9 + 8 + 7 + 6 + 5 + 4 + 3) / 7 = 6,所以选C。
八、排序
8.2 插入排序
201.对5个不同的数据元素进行直接插入排序,最多需要进行的比较次数是(B)。
A.8 B.10 C.15 D.25
Note :
“直接插入排序”在最好情况下,总的比较次数是n-1;在最坏情况下,总的比较次数是n(n-1)/2。
202.在待排序的元素序列基本有序的前提下,效率最高的排序方法是(A)。
A.直接插入排序 B.简单选择排序 C.快速排序 D.归并排序
Note :
对于B和D,简单选择排序和归并排序,其排序效率与待排序元素的初始状态无关;对于C,快速排序算法在待排序的数据已基本有序的情况下效率最低。所以选A。
203.对序列{98,36,-9,0,47,23,1,8,10,7}采用希尔排序,下列序列(A)是增量为4的一趟排序结果。
A.{10,7,-9,0,47,23,1,8,98,36} B.{-9,0,36,98,1,8,23,47,7,10}
C.{36,98,-9,0,23,47,1,8,10,7} D.以上都不对
Note :
注意“希尔排序”是把相隔某个“增量”的记录组成了一个子表,对每个子表分别进行直接插入排序,即,每个子表中元素的个数是不一定,这取决于待排序表中初始总的元素个数。比方说此题中,若增量为4,那么第一个子表为{98, 47, 10},所以进行插入排序后第一个元素为10,其他子表以此类推。所以选A。
204.[2009真题] 若数据元素序列{11,12,13,7,8,9,23,4,5}是采用下列排序方法之一得到的第二趟排序后的结果,则该排序算法只能是(B)。
A.冒泡排序 B.插入排序 C.选择排序 D.2路归并排序
Note :
根据首尾四个元素可以立马排除AC,而2路归并排序经过两趟排序后应该有每四个元素是有序的,但是前四个元素就不连续,所以D错。插入排序经过两趟排序后前三个元素有序,满足条件。
205.[2012真题] 对同一待排序序列分别进行折半插入排序和直接插入排序,两者之间可能的不同之处是(D)。
A.排序的总趟数 B.元素的移动次数
C.使用辅助空间的数量 D.元素之间的比较次数
Note :
相较于直接插入排序,折半插入排序仅减少了比较元素的次数,且该比较次数与待排序元素表的初始状态无关,仅取决于表中的元素个数n;而元素的移动次数并未改变,两者的移动次数都取决于待排序元素表的初始序列。
206.[2014真题] 用希尔排序方法对一个数据序列进行排序时,若第1躺排序结果为9,1,4,13,7,8,20,23,15,则该趟排序采用的增量(间隔)可能是(B)。
A.2 B.3 C.4 D.5
207.[2015真题] 希尔排序的组内排序采用的是(A)。
A.直接插入排序 B.折半插入排序 C.快速排序 D.归并排序
208.[2018真题] 对初始数据序列(8,3,9,11,2,1,4,7,5,10,6) 进行希尔排序。若第一趟排序结果为(1,3,7,5,2,6,4,9,11,10,8),第二趟排序结果为(1,2,6,4,3,7,5,8,11,10,9),则两趟排序采用的增量(间隔)依次是(D)。
A.3,1 B.3,2 C.5,2 D.5,3
8.3 交换排序
209.[2010真题] 对一组数据(2,12,16,88,5,10)进行排序,若前3趟排序结果如下:
第一趟排序结果:2,12,16,5,10,88
第二趟排序结果:2,12,5,10,16,88
第三趟排序结果:2,5,10,12,16,88
则采用的排序方法可能是(A)。
A.冒泡排序 B.希尔排序 C.归并排序 D.基数排序
Note :
每趟排序后,都使剩余的最大的元素排在最后,满足冒泡排序的特点。对于B希尔排序,步长d无论选择1,2,3,4,5,都无法满足第一趟排序的结果;对于C归并排序,两两归并,第一趟应该不变;对于D基数排序,无论从个位还是十位排,都不满足第一趟排序。
210.[2010真题] 采用递归方式对顺序表进行快速排序。下列关于递归次数的叙述中,正确的是(D)。
A.递归次数与初始数据的排列次序无关
B.每次划分后,先处理较长的分区可以减少递归次数
C.每次划分后,先处理较短的分区可以减少递归次数
D.递归次数与每次划分后得到的分区的处理顺序无关
Note :
递归次数与各元素的初始排列有关。若每次划分后分区比较平衡,则递归次数少;若分区不平衡,则递归次数多。递归次数与处理顺序是没有关系的。
211.[2011真题] 为实现快速排序算法,待排序序列宜采用的存储方式是(A)。
A.顺序存储 B.散列存储 C.链式存储 D.索引存储
Note :
选项B和D,散列存储和索引存储,只用于散列表/索引结构的物理存储。由于顺序表“随机存取”的特性,绝大部分内部排序算法只适用于顺序存储的线性表。
212.[2014真题] 下列选项中,不可能是快速排序第2趟排序结果的是(C)。
A.2,3,5,4,6,7,9 B.2,7,5,6,4,3,9
C.3,2,5,4,7,6,9 D.4,2,3,5,7,6,9
Note :
①快排要特别注意pivot“边界情况”,即privot = 最大值/最小值的情况。
对于A,可以第一趟6,第二趟3和7;对于B,可以第一趟2,第二趟9(Vice Versa);
对于C,第一趟只能选出9,第二趟没得选了;对于D,只能第一趟9,第二趟5;
②快排的阶段性特性:第i趟完成时,会有至少i个元素出现在它最终的位置,即左边的元素都比它小,右边的元素都比它大。将题目中的序列排序好是2,3,4,5,6,7,9,将ABCD依次与之对照,发现只有C是仅有一个元素与之对应,即仅有一个元素出现在了最终位置上,所以C一定不是快排第二趟的结果。
213.[2019真题] 排序过程中,对尚未确定最终位置的所有元素进行一遍处理称为一“趟”。下列序列中,不可能是快速排序第二趟结果的是(D)。
A.5,2,16,12,28,60,32,72 B.2,16,5,28,12,60,32,72
C.2,12,16,5,28,32,72,60 D.5,2,12,28,16,32,72,60
Note :
同212题(上一题)类似,不过此题不能用结论做,只能用定义来做。
对于A,只能第一趟72,第二趟28;对于B,可以第一趟2,第二趟72(Vice Versa);
对于C,可以第一趟28,第二趟2和32;对于D,第一趟只能选出12或者32,但无论选12还是32,第二趟都没得选了。
8.4 选择排序
214.简单选择排序算法的比较次数和移动次数分别为(C)。
A.O(n), O(log[2]n) B.O(log[2]n), O(n^2)
C.O(n^2), O(n) D.O(nlog[2]n), O(n)
215.有一组数据(15,9,7,8,20,-1,7,4),用堆排序的筛选方法建立的初始小根堆为(C)。
A.-1,4,8,9,20,7,15,7 B.-1,7,15,7,4,8,20,9
C.-1,4,7,8,20,15,7,9 D.A,B,C均不对
Note :
注意题干中未强调“依次”,所以要将整个数组中的元素按照完全二叉树的结构一一排列开来,然后再统一调整。
216.在含有n个关键字的小根堆中,关键字最大的记录有可能存储在(B)位置。
A.n/2 B.n/2 + 2 C.1 D.n/2 - 1
Note :
"小根堆",关键字最大的记录一定存储在堆所对应的完全二叉树的叶子结点中,而完全二叉树中叶子结点的范围是[(⌊n/2⌋+1), n]。可知ACD都错。
217.下列4种排序方法中,排序过程中的比较次数与序列的初始状态无关的是(A)。
A.选择排序法 B.插入排序法 C.快速排序法 D.冒泡排序法
Note :
注意题干中问的是”比较“次数:
对于A,简单选择排序元素间比较的次数与序列的初始状态无关,始终是n(n-1)/2,因此时间复杂度始终是O(n^2)。
对于B,直接插入排序每趟操作都分为比较关键字和移动元素,而比较次数和移动次数取决于待排序表的初始状态;在最好情况下,表中元素已经有序,此时每插入一个元素,都只需比较一次而不用移动元素,因而时间复杂度为O(n)。
对于C,快速排序的最坏情况对应于初始排序表基本有序或基本逆序时,得到最坏情况下的时间复杂度为O(n^2)。
对于D,冒泡排序当初始序列有序时,第一趟冒泡后就直接跳出循环,比较次数为n-1,移动次数为0,从而最好情况下的时间复杂度为O(n)。
218.[2009真题] 已知关键字序列为5,8,12,19,28,20,15,22是小根堆,插入关键字3调整好后得到的小根堆是(A)。
A.3,5,12,8,28,20,15,22,19 B.3,5,12,19,20,15,22,8,28
C.3,8,12,5,20,15,22,28,19 D.3,12,5,8,28,20,15,2219
219.[2011真题] 已知序列25,13,10,12,9是大根堆,在序列尾部插入新元素18,将其再调整为大根堆,调整过程中元素之间进行的比较次数是(B)。
A.1 B.2 C.4 D.5
Note :
10<18,25>18,两次。(联系建立大根堆的代码)
220.[2015真题] 已知小根堆为8,15,10,21,34,16,12,删除关键字8之后需重建堆,在此过程中,关键字之间的比较次数是(C)。
A.1 B.2 C.3 D.4
Note :
根据堆排序的规则,删除堆顶元素8后,需要用堆底最后一个元素拿来补位,即小根堆堆顶元素从8变为12,然后对该小根堆进行调整。根据建立大根堆的代码,可类比推得建立小根堆的代码(联系),原来已经有序的元素(没有变化的子树)不需要再进行比较,首先15和10比较,10更小,指针指向10,然后堆顶元素12和10比较,12>10,所以交换12和10,交换后,比较10和它的子树16,符合小根堆规则,因此共比较了3次。
221.[2018真题] 在将序列(6,1,5,9,8,4,7)建成大根堆时,正确的序列变化过程是(A)。
A.6,1,7,9,8,4,5 --> 6,9,7,1,8,4,5 --> 9,6,7,1,8,4,5 --> 9,8,7,1,6,4,5
B.6,9,5,1,8,4,7 --> 6,9,7,1,8,4,5 --> 9,6,7,1,8,4,5 --> 9,8,7,1,6,4,5
C.6,9,5,1,8,4,7 --> 9,6,5,1,8,4,7 --> 9,6,7,1,8,4,5 --> 9,8,7,1,6,4,5
D.6,1,7,9,8,4,5 --> 7,1,6,9,8,4,5 --> 7,9,6,1,8,4,5 --> 9,7,6,1,8,4,5 --> 9,8,6,1,7,4,5
222.[2020真题] 下列关于大根堆(至少含2个元素)的叙述中,正确的是(C)。
Ⅰ.可以将堆视为一棵完全二叉树
Ⅱ.可以采用顺序存储方式保存堆
Ⅲ.可以将堆视为一棵二叉排序树
Ⅳ.堆中的次大值一定在根的下一层
A.仅Ⅰ、Ⅱ B.仅Ⅱ、Ⅲ C.仅Ⅰ、Ⅱ和Ⅳ D.Ⅰ、Ⅲ和Ⅳ
Note :
Ⅲ肯定错,排除BD,Ⅳ对,所以选C。
223.[2021真题] 将关键字6,9,1,5,8,4,7依次插入到初始为空的大根堆H中,得到的H是(B)。
A.9,8,7,6,5,4,1 B.9,8,7,5,6,1,4
C.9,8,7,5,6,4,1 D.9,6,7,5,8,4,1
Note :
注意题干强调是“依次”,所以从第二个元素开始,每插入一个元素都要确保满足大根堆的特性,及时做出调整。
8.5 归并排序和基数排序
224.[2013真题] 对给定的关键字序列110,119,007,911,114,120,122进行基数排序,第2趟分配收集后得到的关键字序列是(C)。
A.007,110,119,114,911,120,122 B.007,110,119,114,911,122,120
C.007,110,911,114,119,120,122 D.110,120,911,122,114,007,119
Note :
没得说,简单画个图就出来了。
225.[2016真题] 对10TB的数据文件进行排序,应使用的方法是(B)。
A.希尔排序 B.堆排序 C.快速排序 D.归并排序
Note :
堆排序适合关键字较多的情况。
226.[2017真题] 在内部排序时,若选择了归并排序而未选择插入排序,则可能的理由是(B)。
Ⅰ.归并排序的程序代码更短 Ⅱ.归并排序的占用空间更少
Ⅲ.归并排序的运行效率更高
A.仅Ⅱ B.仅Ⅲ C.仅Ⅰ、Ⅱ D.仅Ⅰ、Ⅲ
Note :
对于Ⅰ,归并排序的代码更长好吧,骑驴找马。对于Ⅱ,归并排序的占用空间更多,空间复杂度归并排序O(n)>插入排序O(1);对于Ⅲ,时间复杂度归并排序O(nlog[2]n)<插入排序O(n^2)。
227.[2021真题] 设数组S[] = {93,946,372,9,146,151,301,485,236,327,43,892},采用最低位优先(LSD)基数排序将S排列成升序序列。若第一趟分配、收集后,元素372之前、之后紧邻的元素分别是(C)。
A.43,892 B.236,301 C.301,892 D.485,301
8.6 各种内部排序算法的比较及应用
228.排序趟数与序列的原始状态无关的排序方法是(B)。
Ⅰ.直接插入排序 Ⅱ.简单选择排序 Ⅲ.冒泡排序 Ⅳ.基数排序
A.Ⅰ、Ⅲ B.Ⅰ、Ⅱ、Ⅳ C.Ⅰ、Ⅱ、Ⅲ D.Ⅰ、Ⅳ
Note :
注意题干问的是“排序趟数”,而不是比较次数或者移动次数。交换类的排序算法(冒泡和快排),其排序趟数和原始序列状态有关,所以Ⅲ不能选。对于Ⅰ直接插入排序,每趟排序都插入一个元素,所以排序趟数固定为n-1;对于Ⅱ简单选择排序,每趟排序都选出一个最小(或最大)的元素,所以排序趟数固定为n-1;对于Ⅳ基数排序,每趟排序都要进行“分配”和“收集”,故排序趟数固定为d(d指d元组)。
229.排序趟数与序列的原始状态有关的排序方法是(C)排序法。
A.插入 B.选择 C.冒泡 D.快排
Note :
与上一题(228题)对应,此题问的是“有关”,对于C冒泡排序,当初始序列已经有序时,第一趟冒泡不会发生元素交换,从而直接跳出循环,只进行了一趟排序。AB上一题说过了。对于D快速排序,每个元素要确定它的最终位置都需要一趟排序,所以无论序列初态如何,都需要n趟排序,注意快速排序虽然与初始序列的状态有关,但这个“有关”是指排序的时间复杂度,而不是排序的趟数。
230.一般情况下,以下查找效率最低的数据结构是(C)。
A.有序顺序表 B.二叉排序树 C.堆 D.平衡二叉树
Note :
堆是用来排序的,在查找时它是无序的,所以效率低。
231.[2012真题] 在内部排序过程中,对尚未确定最终位置的所有元素进行一遍处理称为一趟排序。下列排序方法中,每趟排序结束都至少能够确定一个元素最终位置的方法是(A)。
Ⅰ.简单选择排序 Ⅱ.希尔排序 Ⅲ.快速排序 Ⅳ.堆排序 Ⅴ.2路归并排序
A.仅Ⅰ、Ⅲ、Ⅳ B.仅Ⅰ、Ⅲ、Ⅴ C.仅Ⅱ、Ⅲ、Ⅳ D.仅Ⅲ、Ⅳ、Ⅴ
232.[2015真题] 下列排序算法中,元素的移动次数与关键字的初始排序次序无关的是(C)。
A.直接插入排序 B.起泡排序 C.基数排序 D.快速排序
Note :
排除法——假设序列已经有序,则ABD的“移动次数”均为0;对于C,基数排序与序列的初始状态无关。
233.[2017真题] 下列排序方法中,若将顺序存储更换为链式存储,则算法的时间效率会降低的是(D)。
Ⅰ.插入排序 Ⅱ.选择排序 Ⅲ.起泡排序 Ⅳ.希尔排序 Ⅴ.堆排序
A.仅Ⅰ、Ⅱ B.仅Ⅱ、Ⅲ C.仅Ⅲ、Ⅳ D.仅Ⅳ、Ⅴ
Note :
顺序存储和链式存储的根本区别是:顺序存储具有“随机存取”的特性,而链式存储不具有。希尔排序根据步长d查找组内元素,堆排序在建堆过程中利用了元素下标之间的关系,所以它们都利用了顺序存储“随机存取”的特性,而链式存储不支持这一特性,所以时间复杂度会增加。
234.[2019真题] 选择一个排序算法时,除算法的时空效率外,下列因素中,还需要考虑的是(D)。
Ⅰ.数据的规模 Ⅱ.数据的存储方式 Ⅲ.算法的稳定性 Ⅳ.数据的初始状态
A.仅Ⅲ B.仅Ⅰ、Ⅱ C.仅Ⅱ、Ⅲ、Ⅳ D.Ⅰ、Ⅱ、Ⅲ、Ⅳ
235.[2020真题] 对大部分元素已有序的数组排序时,直接插入排序比简单选择排序效率更高,其原因是(A)。
Ⅰ.直接插入排序过程中元素之间的比较次数更少
Ⅱ.直接插入排序过程中所需的辅助空间更少
Ⅲ.直接插入排序过程中元素的移动次数更少
A.仅Ⅰ B.仅Ⅲ C.仅Ⅰ、Ⅱ D.Ⅰ、Ⅱ和Ⅲ
Note :
对于Ⅰ,直接插入排序在最好情况下,表中元素已经有序,此时每插入一个元素,都只需比较一次而不用移动元素;简单选择排序在最好情况下,此时对应的表已经有序,但元素间比较的次数与序列的初始状态无关,始终是n(n-1)/2次。所以Ⅰ对。
对于Ⅱ,两者的空间复杂度都是O(1)。所以Ⅱ错。
对于Ⅲ,当初始序列已经有序时,两者的移动次数均为0;而在更一般的情况下,直接插入排序每趟排序都需要依次向后挪位,而简单选择排序只需要找到最小元素来交换位置,后者的移动次数少很多。所以Ⅲ错。
8.7 外部排序
236.设在磁盘上存放有375000个记录,做5路平衡归并排序,内存工作区能容纳600个记录,为把所有记录排好序,需要做(B)趟归并排序。
A.3 B.4 C.5 D.6
Note :
可知此题考查“外部排序”,首先要求得初始归并段的个数,375000 / 600 = 625。对这625个初始归并段做5路平衡归并排序,最终要归并成1个有序的初始归并段。625个怎么变成的1个呢?显然,625是5的四次方,即5^4 = 625,所以选B。
237.在下列关于外部排序过程输入/输出缓冲区作用的叙述中,不正确的是(D)。
A.暂存输入/输出记录 B.内部归并的工作区
C.产生初始归并段的工作区 D.传送用户界面的消息
Note :
在外部排序过程中输入/输出缓冲区就是排序的内存工作区WA,例如做m路平衡归并需要m个输入缓冲区和1个输出缓冲区,用以存放参加归并和归并完成的记录。在产生初始归并段时也可用作内部排序的工作区。但它没有“传送用户界面的消息”的任务。
238.[2013真题] 已知三叉树T中6个叶结点的权分别为2,3,4,5,6,7,T的带权(外部)路径长度最小是(B)。
A.27 B.46 C.54 D.56
Note :
由“判定虚段”的公式可知(公式见下一题的解析),7个归并段刚好可以构成一棵严格3叉树。而不巧的是此题是6个归并段,显然要增加一个空归并段(权值为0的结点),选取权值最小的三个结点0,2,3合并,然后根据哈夫曼树的思想以此类推,最终得到该三叉树的WPL = 46。
239.[2019真题] 设外存上有120个初始归并段,进行12路归并时,为实现最佳归并,需要补充的虚段个数是(B)。
A.1 B.2 C.3 D.4
Note :
①首先要熟悉最佳归并树的构造:叶结点表示初始归并段,上面的权值表示该归并段的长度,叶结点到根结点的路径长度表示其参加归并的趟数,各非叶结点(即分支结点)代表归并产生的新归并段,根结点则表示最终生成的最终归并段。
②设T = (叶结点总数 - 1)%(归并路数 - 1):
若T = 0,则表示当前的所有叶结点正好可以构造一棵归并树(树的叉数和归并路数相等);
若T ≠ 0,则表示当前的所有叶结点无法构造一棵归并树,需要额外补充虚段(权值为0的结点),而补充的权值为0的叶结点的数目 = 归并路数 - T - 1。
由①中定义可知,当前叶结点总数是120;由②中公式可知,(120 - 1)%(12 - 1) = 9 ≠ 0,所以需要补充12 - 9 - 1 = 2个虚段,所以选B。
Δ总结
- 总共239道题目,超出预期39道😂,一共八章后三章就占了100多道题目。
- 仅从做题角度出发,6.4—图的应用,7.4—B树与B+树,以及8.6—各种内部排序算法的比较及应用,这几个小节的选择题难度相对比较大,需要读者多加留心,多多练习。
- 对于408 —《数据结构》的大题部分,也就是算法题和应用题了,up也会出博文讲解,不过目前只计划了算法题的博客,应用题看时间吧,感谢阅读!
System.out.println("END--------------------------------------");