前言
文章里所有的选择题源自山科软工数据结构课程作业所出,将其中一些重点难点以及易混的题目摘出,并附有答案和较为详细的分析。简单题就一两句话,难些的题图文并茂。
文章中的解释以及图片部分来源于网络,但大部分由作者个人分析,所以有问题欢迎指出。
作业一 数据结构基本知识
1.数据的逻辑结构是指数据的各数据项之间的逻辑关系。
F 各元素之间的逻辑关系
2.抽象数据类型中基本操作的定义与具体实现有关
F 抽象的无关
3.数据的()包括集合、线性结构、树形结构和图形结构四种基本类型。
B.逻辑结构
4.数据在计算机内存中表示的是
A.数据的存储结构
5.在决定选取何种存储结构时,一般不考虑()
A.各结点的值如何
6.数据项是不可分割的最小单位,数据元素是数据的基本单位,数据项是构成数据元素的基本单位
作业二 复杂度分析
1.时间复杂度n²不一定比n*logn花费的时间长
x=n; //n>1
y=0;
while( x≥(y+1)*(y+1) )
y++;
时间复杂度为O(n^0.5) 其中x≥(y+1)(y+1)可以转换为n>=(y+1)(y+1)即有n0.5>=y+1,所以y<=n0.5-1,因此时间复杂度为 o(n^0.5)
if ( A > B ) {
for ( i=0; i<N*N/100; i++ )
for ( j=N*N; j>i; j-- )
A += B;
}
else {
for ( i=0; i<N*2; i++ )
for ( j=N*3; j>i; j-- )
A += B;
}
时间复杂度为O(N^4)
int func ( int n )
{ int i = 0, sum = 0;
while ( sum < n ) sum += ++i;
return i;
}
sum+=++i 也就是 ++i; sum=sum+i ,进行的第K趟循环,sum=(1+k)*k/2 也就是需要进行O(n^0.5)趟循环 此为复杂度
for(i=0; i<n; i++)
for(j=i; j>0; j/=2)
printf(“%d\n”, j);
因为第二个for中的j每次除以2 所以整体的时间复杂度为O(NlongN)
6.
虽然都有平方 但是B中N方在log中 所以最小
7.计算机算法必须具备输入、输出和可行性、确定性和有穷性等五个特性。
作业三 线性表抽象数据类型定义及顺序表操作
1.对于顺序存储的长度为N的线性表,访问节点和增加结点的时间复杂度分别对应为O(1)和O(N)
T 访问可以通过下标直接访问,但增加结点要后移
2.顺序表中第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是( ) A.100 B.105 C.108 D.110
C 元素的存储地址是它的首地址,所以第一个为100 则第五个为108
3.要将一个顺序表{a0 ,a1 ,……,an−1 }中第i个数据元素ai (0≤i≤n-1) 删除,需要移动(n-i-1 )个数据元素。
从i+1到n-1,一共是(n-1-(i+1))+1即(n-i-1)个元素
4.若长度为n的线性表采用顺序存储结构,那么删除它的第i个数据元素之前,需要它一次向前移动()个数据元素。
因为题目说的是第 i 个元素 所以只需要n-i即为所需要移动的元素
5.若长度为n的线性表采用顺序结构,在第i个数据元素之前插入一个元素,需要它依次向后移动()个元素。
看清题目 第i个元素之前插入 也就是说从第i个到最后一个都要往后移 也就是n-i+1
6.线性表L=(a1, a2 ,……,an )用一维数组表示,假定删除线性表中任一元素的概率相同(都为1/n),则删除一个元素平均需要移动元素的个数是()
删除第一个需要移动n-1个 删除最后一个需要移动0个 所以 (n-1)/2
作业五 单链表
1.在具有N个结点的单链表中,访问结点和增加结点的时间复杂度分别对应为O(N)和O(1)。
注意 正好和顺序表反着
2.将两个结点数都为N且都从小到大有序的单向链表合并成一个从小到大有序的单向链表,那么可能的最少比较次数是:N
其中一个链表都大于另一个 只需要比较N次 然后把另一个接到后面即可
3.在一个含有n个结点的有序单链表中插入一个新结点,使单链表仍然保持有序的算法的时间复杂度是( )
O(N) 虽然插入的操作O(1) 但找到要插入的地方需要O(N)
4.
这个C应该是说通过纸面的计算吧 不能像顺序存储那样直接找到,其他选项没毛病
作业六 改进的单链表
1.某线性表中最常用的操作是在最后一个元素之后插入一个元素和删除第一个元素,则采用什么存储方式最节省运算时间?
用 仅有尾指针的单循环链表
2.若某表最常用的操作是在最后一个结点之后插入一个结点或删除最后一个结点。则采用哪种存储方式最节省运算时间?
用 带头结点的双循环链表
3.在链表中若经常要删除表中最后一个结点或在最后一个结点之后插入一个新结点,则宜采用()存储方式。
用尾指针标识的循环单链表
4.若某表最常用的操作是在最后一个结点之后插入一个结点或删除最后一个结点,则采用()存储方式最节省运算时间。
带表头附加结点的双循环链表
5.在一个长度为n(n>1)的单链表上,设有头和尾两个指针,执行()操作与链表的长度有关。
B.删除单链表中的最后一个元素 因为要保证删除后仍有尾指针,所以所以要从头找到倒数第二个才行
6.如果对线性表的运算只有4种,即删除第一个元素,删除最后一个元素,在第一个元素前面插入新元素,在最后一个元素的后面插入新元素,则最好使用()。
用 只有表头指针没有表尾指针的循环双链表
7.采用多项式的非零项链式存储表示法,如果两个多项式的非零项分别为N1和N2个,最高项指数分别为M1和M2,则实现两个多项式相乘的时间复杂度是:
- O*(N1×N2)
作业七 栈及其应用
1.若一个栈的输入序列为1,2,3,…,N,输出序列的第一个元素是i,则第j个输出元素是j−i−1。
F 答案是不确定 因为可以边进边出
但如果输出序列的第一个为N 则第j个为n-j+1
2.给定一个堆栈的入栈序列为{ 1, 2, ⋯, n },出栈序列为{ p1, p2, ⋯, p**n }。如果p2=n,则存在多少种不同的出栈序列?
n-1种 出栈的第二个是最后进栈的 所以有n-1种
作业八 栈与递归
1.将5个字母ooops
按此顺序入栈,则有多少种不同的出栈顺序可以仍然得到ooops
?
答案 5 种
2.若借助堆栈将中缀表达式a+b*c+(d*e+f)*g
转换为后缀表达式,当读入f
时,堆栈里的内容是什么(按堆栈自底向上顺序)?
+( +
分析一下 :读a 输出 ,+ 入栈,b输出,*入栈,c输出,读+,因为 *的优先级比+高,所以 *先出栈,+再入栈,遇到( 入栈,d输出, *入栈 ,e输出,读到+ ,因为 *比+优先级高 ,所以 *先出栈,+再入栈 ,读到f输出。
总结就是 +入 *入 *出 +入 ( 入 *入 *出 +入 +( +
作业九 队列及其应用
1.如果循环队列用大小为m
的数组表示,且用队头指针front
和队列元素个数size
代替一般循环队列中的front
和rear
指针来表示队列的范围,那么这样的循环队列可以容纳的元素个数最多为:
m个 因为size表示元素个数 所以最后一个位置也放元素
2.如果循环队列用大小为m
的数组表示,队头位置为front
、队列元素个数为size
,那么队尾元素位置rear
为:
(front+size-1)%m 下标要-1
作业十 数组和广义表
对称阵
对于给定一个元素 a(i,j)
1.求它所在行的前面的行所以元素的和
Sn= n(a1+an)/2 = (i-1)(1+i-1)/2 = i(i-1)/2
2.求它所在行它前面元素的个数
就是列数减一 j-1
3.所以假设K为一维数组下标 ,则
K= i(i-1)/2+j-1 (i>=j)
K=j(j-1)/2+i-1 (i<j)
三对角矩阵
三对角矩阵就是对角线、临近对角线的上下次对角线上有元素,其余位置均为0的矩阵
如上图,但是要注意,图中是从0到n-1的元素
然后按照不同存储方式,有
(1)行优先存储
(2)列优存储
对应一维数组的下标很好记忆
看一道题
如果直接按照刚才的结论,K的位置应该是66*2+65=197, 但是答案是195,问题在于题目中的数组序号和存储序号不同
在上面基本图中 数组是从 0到n-1 但是题目中是给的1到n,然后存储到1-n的一维数组中,所以计算时应该是
2*(66-1)+ 65 = 195
广义表
概念
广义表:n ( ≥0 )个表元素组成的有限序列,记作LS = (a0, a1, a2, …, an-1)
LS是表名,ai是表元素,它可以是表 (称为子表),可以是数据元素(称为原子)。n为表的长度。n = 0 的广义表为空表。
长度/深度
长度:第一层元素的个数
深度:括号的重数
表头/表尾
表头:广义表LS非空时,第一个元素ɑ1为表头,可以为单元素,也可以为一个子表。
表尾:非空广义表除去表头以外的其余元素构成的表(ɑ2,ɑ3,…ɑn)为LS的表尾,表尾一定是一个表。
基本运算:
求表头GetHead(L)/Head(L)
求表尾GetTail(L)/Tail(L)
两种类型题:
(1)给出广义表,根据操作求结果
(2)给出广义表,根据结果求操作
题型1:根据操作求结果
例3:下列广义表,求表头表尾
A=(a,b) GetHead(A)= a GetTail(A)=(b)
A=(a) GetHead(A)=a GetTail(A)=()
A=((a)) GetHead(A)= (a) GetTail(A)=()
例4:广义表A=(a,b,(c,d),(e,(f,g)))
GetHead(GetTail(GetHead(GetTail(GetTail(A)))))=d_。
解析:从内向外求
B=GetTail(A)=(b,(c,d),(e,(f,g)))
C=GetTail(B)=((c,d),(e,(f,g))
D=GetHead©=(c,d)
E=GetTail(D)=(d)
F=GetHead(E)=d
作业十一 树与二叉树概念与基本操作
二叉树的一些性质
1.对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1。
2.在二叉树的第i层上至多有2^(i-1)个结点(i≥1)
3.深度为k的二叉树至多有2^k - 1个节点,至少为k个
4.具有n个节点的完全二叉树的深度为[log2n]+1向下取整
5.总节点个数为根节点+子节点,如果题目给出各种度的节点个数,要求节点总数,只需要把所以个数*度数求和再加1即可
如果忘了性质或者不会做,个数不多就在纸上画
题目
1.存在一棵总共有2016个结点的二叉树,其中有16个结点只有一个孩子。
F
假设没有孩子的结点(叶结点)个数为n₀,只有一个孩子的结点(度为1的结点)个数为n₁,有两个孩子的结点(度为2的结点)个数为n₂。
则n₀+n₁+n₂=2016
∵n₀=n₂+1(二叉树的性质:叶结点个数等于度为2的结点个数加1)
∴n₀+n₁+n₂=2016
⇨n₂+1+16+n₂=2016
⇨2n₂=1999
n₂除不尽,所以答案错误。
2.如果一棵非空k(k≥2)叉树T中每个非叶子结点都有k个孩子,则称T为正则k叉树。若T的高度为h(单结点的树h=1),则T的结点数最多为:(k^h−1)/(k−1)
如果一棵非空k(k≥2)叉树T中每个非叶子结点都有k个孩子,则称T为正则k叉树。若T的高度为h(单结点的树h=1),则T的结点数最少为:k(h−1)+1
如果一棵非空k(k≥2)叉树T中每个非叶子结点都有k个孩子,则称T为正则k叉树。若T有m个非叶子结点,则T中的叶子结点个数为:m(k−1)+1
关于这个正则K叉树,网上资料比较少,考试选择题就代数试试,公式能记住就记
3.设高为h的二叉树(规定叶子结点的高度为1)只有度为0和2的结点,则此类二叉树的最少结点数和最多结点数分别为:
最多的时候是这样
这样就是一个满二叉树,最多为2^h-1
最少是这样
此时可以很明显发现规律,除了第一层的根节点,其他的层都是两个节点,所以2*(h-1)+1=2h-1
4.在一棵度为4的树T中,若有20个度为4的结点,10个度为3的结点,1个度为2的结点,10个度为1的结点,则树T的叶结点个数是:82
根节点个数为1,子节点个数为20*4+10*3+1*2+10*1 = 122,所以总结点个数为123个,只有叶节点度数为0,其他结点都有度数。由题意得其他结点总数为20+10+1+10 =41个
故叶节点(终端节点)=123-41=82个。
作业十二 二叉树的遍历
1.某二叉树的后序和中序遍历序列正好一样,则该二叉树中的任何结点一定都无右孩子。 T
某二叉树的后序和中序遍历序列正好一样,则该二叉树中的任何结点一定都无右孩子。 F
某二叉树的前序和中序遍历序列正好一样,则该二叉树中的任何结点一定都无左孩子。 T
这种题鲁大师课上给了个方法
例如后序 为 左右中,中序为左中右,因为中必须要遍历,所以要想两者相同,就必须把右划去得到 后序 左_ _中,中序左中 _ _,这样两者就相同了。
2.若一个结点是某二叉树的中序遍历序列的最后一个结点,则它必是该树的前序遍历序列中的最后一个结点。 F
看起来没毛病,但是如果一颗二叉树没有右子树的话,那么中序遍历的最后一个结点是根节点,而前序遍历的最后一个结点是左侧最后一个结点。
3.已知一棵二叉树的先序遍历结果是ABC, 则CAB不可能是中序遍历结果。 T
三个结点画一下就可以看出来。
4.任何一棵二叉树的叶结点在先序、中序和后序遍历序列中的相对次序
不发生改变。因为三种遍历顺序,都是先左后右,所以叶节点相对顺序不变。
5.某二叉树的中序序列和后序序列正好相反,则该二叉树一定是
(2分)
A.空或只有一个结点
B.高度等于其结点数
C.任一结点无左孩子
D.任一结点无右孩子
乍一看好像没有思路,实际还和第一题一个做法。
中序:左中右 后序:左右中 很明显要想相反,中序是中右,后序是右中 所以这个题选C
C选项是B选项的一种,然是如果是没有右孩子的一条链,本题就不符合了。
注意对比下一题进行区分
6.某二叉树的前序和后序遍历序列正好相反,则该二叉树一定是
A.空或只有一个结点
B.高度等于其结点数
C.任一结点无左孩子
D.任一结点无右孩子
同样,前序:中左右 后序:左右中,我们可以看到,左或者右甚至只有头结点,该题都是符合的,因为是单选,而且是选择一定正确的,则选B。如果题目问可能是,则ABCD都对了。
下列线索二叉树中(用虚线表示线索),符合后序线索树定义的是:
A.
B.
C.
D.
这个题也是很经典的一个题了,做错的原因更多是对线索二叉树的概念理解不够深刻。在这里啰嗦一下。
因为二叉树的左右指针有时候为空,所以我们让原本指向左右孩子的指针域但是为NULL的,左指针指向遍历的前驱,右指针指向遍历的后继,当然了如果节点本身指针域就指向孩子,那就不用了。所以看题。
我们先不管线索,得到的遍历顺序应为 d->b->c->a
A中,b没有左孩子,所以它的左指针应该指向它的前驱,也就是d,但是图中指向了a,错误
B中,d没有左孩子也没有前驱,所以左指针指向NULL,没有右孩子但是有后继b,则右指针指向b;b没有左孩子但有前驱d,所以左指针指向d,有右孩子,所以不管;c没有左孩子但有前驱b,所以左指针指向b,没有右孩子但有后继a,所以右指针指向a;a有左右孩子,不管。至此,B正确。
C、D中,错误很多,不具体分析,对照B选项的分析。
8.已知一棵完全二叉树的第6层(设根为第1层)有8个叶子结点,则该完全二叉树的结点个数最多是( )。
完全二叉树的第6层有8个,可以是只有六层,也可以是有七层,但是第六层右侧有八个叶子节点没有孩子。
则六层都有的话是2^6-1=63 然后第六层有2^5=32个,32-8=24,所以还有24个节点有两个孩子,就是2*24=48,一共就是63+48=11
作业十三 树与森林
1.对于一个有N个结点、K条边的森林,不能确定它共有几棵树
F 首先我们知道,一棵树除了根节点,每个节点都有一条边相连,也就说 边数=节点数-1 ,换一下位置,节点数-边数=1,假设森林里有T棵树,那么所有的节点减去所有的边数,得到的即为树的棵数,因此可以确定。
2.将森林转换为对应的二叉树,若在二叉树中,结点u是结点v的父结点的父结点,则在原来的森林中,u和v可能具有的关系是
1.父子关系; 2. 兄弟关系; 3. u的父结点与v的父结点是兄弟关系
选1和2
树不是二叉树
3.设森林F中有三棵树,第一、第二、第三棵树的结点个数分别为M1,M2和M3。则与森林F对应的二叉树根结点的右子树上的结点个数是:
这个很好想,把第一棵树的根节点当二叉树的根节点,右子树连第二棵和第三课。
4.由若干个二叉树组成的森林F中,叶结点总个数为N,度为2的结点总个数为M,则该集合中二叉树的个数为:N-M
叶结点为N个,设N1和N2
二叉树个数=节点数–边数=N+N1+N2-(N1*2+N2)=N-M
作业十四 Huffman树及其应用
1.设一段文本中包含字符{a, b, c, d, e},其出现频率相应为{3, 2, 5, 1, 1}。则经过哈夫曼编码后,文本所占字节数为:25
文本中所占字节数,所以先求出每个字母的哈夫曼编码位数,然后再把位数与出现频率相乘求和,即4*1+4+1+3*2+2*3+1*5=25
2.若以{4,5,6,3,8}作为叶子节点的权值构造哈夫曼树,则带权路径长度是(59)
像求带权路径长的问题,可以把从根节点到叶子节点的边数*权值再求和,也可把非叶子节点的值求和。
3.在哈夫曼树中,任何一个结点它的度都是( )
0或2 哈夫曼树的性质,肯定是由两个节点构成一个新节点,所以只有度为0或2
作业十五 图的概念和存储
题目
1.无向连通图边数一定大于顶点个数减1。
F 不连通的图的边数最少为顶点数减1,如果少了那就没有连到一起,多了便有回路。
2.在一个有向图中,所有顶点的入度与出度之和等于所有边之和的2倍。
F 应该是所有顶点数的2倍
3.如果无向图G必须进行两次广度优先搜索才能访问其所有顶点,则G中一定有回路。
F 应该是有两个连通分量
4.如果无向图G必须进行两次广度优先搜索才能访问其所有顶点,则G一定有2个连通分量。
T 对比上一题
5.在图中自a点开始进行广度优先遍历算法可能得到的结果为:
A. a, e, d, f, c, b
B. a, c, f, e, b, d
C. a, e, b, c, f, d
D. a, b, e, c, d, f
像这种以字母为节点的图,如果要遍历基本都是按字典序的,但是这题吧问的是可能,所以四个结果中有一定错的,也有不按字母序的,所以可以用排除法来做 选D
6.已知无向图G含有16条边,其中度为4的顶点个数为3,度为3的顶点个数为4,其他顶点的度均小于3。图G所含的顶点个数至少是:11
无向图中,度为边的两倍,那么总度为32, 3*4=12 4*3=12,所以目前有24度,还剩8,然后题目问至少多少个,那么就设还剩度为2的,则8/2=4,一共4+3+4=11
7.设无向图的顶点个数为N,则该图最多有多少条边?
N(N−1)/2
计算一下记住。
8.若无向图G =(V,E)中含10个顶点,要保证图G在任何情况下都是连通的,则需要的边数最少是:37
这题很巧妙,如果10个点在任意情况下联通,那么可以想成9个点已经联通,最后只需要用一条边把第十个点连入,所以就是9*8/2+1=37
9.如果G是一个有28条边的非连通无向图,那么该图顶点个数最少为多少? 9
注意是非连通,所以要先计算出,28条能连通多少,代入公式得顶点数为8,因为没有连通,则加一是9
10.下列关于无向连通图特征的叙述中,正确的是:
- 所有顶点的度之和为偶数
- 边数大于顶点个数减1
- 至少有一个顶点的度为1
只有1
1,每条边连接两个顶点,所有顶点的度之和等于边数的2倍,是偶数,正确
2,如两个顶点一条边的图就不满足这个条件,错
3,如三个顶点三条边连成一个三角形的图每个顶点度为2,错
11.在N个顶点的无向图中,所有顶点的度之和不会超过顶点数的多少倍?
(N-1)倍 其实就是每个点都与其他点相连,最好的例子就是三角形。
12.具有N(N>0)个顶点的无向图至多有多少个连通分量?
那就是N个不连通的点。
“连通”两字概念辨析
1.对于无向图而言,如果图中的某两个点,例如:存在W到V的路径,那么我们说w和v是连通的;进一步如果图中任意两点之间都是存在路径的,那么我们说这个是连通的,即可称为连通图。
2.连通子图:设G=(V,E)和G=(V
,E),如果V
是V的子集,并且E是E的子集,那么称G
是G的子图。如果子图是连通的,那么就是连通子图,这不难理解。(需要注意,并不是你随便从G=(V,E))中挑的V的子集V跟E的子集E
,就能构成一个子图,因为有可能挑的边V跟顶点E没有关系,那也就构不成一个图了)
3.极大连通子图(连通分量)与极小连通子图:
a.极大连通子图就是连通分量。
对于极大的理解是,极大针对的是边,也就是边要越多越好,最后生成的子图中已经**包含了原图G中的与子图G中顶点相关的所有边**。简单来说,凡是与G
中顶点有关的边,全都要(这也就隐含了,如果我们在一个极大连通子图中删去一些边,它依旧可能是连通的,可以与极小进行比较理解)。生成一个极大连通子图的过程可以理解为:从一个顶点出发,逐个添加所有与这个子图有边的顶点,直到将所有连通的顶点全都纳入这个图中,这时生成的子图就是极大的。
b.极小比较好理解,也是针对的边,就是在保持子图中所有顶点连通的前提下,纳入最少的边,生成的图;也就是对于一个极小连通子图而言,再去掉任意一条边,那就非连通了。
4.强连通图与强连通分量:
这两个是针对有向图而言的,有向图中,若W到V与V到W之间都有路径,那么就说这两个顶点是强连通的,如果图中每对顶点直接都是强连通的,那么这个图就是强连通图了。而有向图的极大强连通子图就是强连通分量。
注意:我们一般是在无向图中讨论连通性**,在有向图中讨论强连通性。
不知道有没有这样的困惑,既然包含了所有的边,那为什么不叫最大呢?极大本身已经要求包含所有的顶点了,那不就是原图G了吗?
关键在于,只考虑到了连通图G了,当原图G本身就是个连通图,那么极大连通子图就是原图了,此时也就是最大了。那如果G是非连通的呢?那就导致,上边那个生成极大连通子图的过程走一次,并不能将所有边纳进来,也就是说,一个非连通的图可能会有好几个极大连通子图(其实也就是好几个连通分量),此时也就不是最大了,而是极大。
作业十六 图的遍历与最小生成树
给定有权无向图的邻接矩阵如下,其最小生成树的总权重是:
答案是8 在纸上画一下就行,根据两个算法的思路
2.给定有权无向图如下。关于其最小生成树,下列哪句是对的?
A.最小生成树不唯一,其总权重为23
B.最小生成树唯一,其总权重为20
C.边(B, F)一定在树中,树的总权重为23
D.边(H, G)一定在树中,树的总权重为20
这个题选A 这个根据prim算法好做,反正就画一画试试就知道了
作业十七 拓扑排序与关键路径
1.在拓扑排序算法中用堆栈和用队列产生的结果会不同吗?
A.以上全不对
B.是的肯定不同
C.肯定是相同的
D.有可能会不同
这个很显然,可能会产生不同,因为当遇到路径中同时可以选择的节点时,队列和栈就不一样了。
2.若将n个顶点e条弧的有向图采用邻接表存储,则拓扑排序算法的时间复杂度是:
A.O*(*n)
B.O*(*n^2)
C.O*(n×*e)
D.O*(n+*e)
答案是D
3.在AOE网中,什么是关键路径?
A.从第一个事件到最后一个事件的最短路径
B.最长回路
C.从第一个事件到最后一个事件的最长路径
D.最短回路
选C。关键一词可以想成完成这些事中关键的部分,他们对这些事情的完成起关键作用,如果在执行过程中,他们没有完成,那么其他的任务完成了也只能等着,所以是从第一个时间到最后一个事件的最长路径。
4.对下图进行拓扑排序,可以得到不同的拓扑序列的个数是:
A.1
B.2
C.3
D.4
选 C 三种。 首先先是A,A划掉后b和e可选,先选e,则ebcd,若先选b则bced和becd。纸上画一下很简单。
作业十八 最短路
1.在一个有权无向图中,若b
到a
的最短路径距离是12,且c
到b
之间存在一条权为2的边,则c
到a
的最短路径距离一定不小于10。 T
因为题目中说了,b到a的最短路径距离是12,那如果c到b有一条权为2的边,那么如果c到a有一条边小于10的话,那么b到a就可以走b-c-a这条路,那么必然最短路径小于12,所以一定大于等于10,论述正确。
2.使用迪杰斯特拉(Dijkstra)算法求下图中从顶点1到其他各顶点的最短路径,依次得到的各最短路径的目标顶点是:
A.5, 2, 3, 4, 6
B.5, 2, 6, 3, 4
C.5, 2, 4, 3, 6
D.5, 2, 3, 6, 4
根据Dijkstra算法,从1号出发,逐步找就可以,可能有点麻烦,最好是在纸上,把每一步到达的距离写一下。
若要求在找到从S
到其他顶点最短路的同时,还给出不同的最短路的条数,我们可以将Dijkstra算法略作修改,增加一个count[]
数组:count[V]
记录S
到顶点V
的最短路径有多少条。则count[V]
应该被初始化为:
(3分)
A. count[S]=0; 对于其他顶点
V则令
count[V]=1
B. count[S]=1; 对于其他顶点
V则令
count[V]=0
C.对所有顶点都有count[V]=1
D.对所有顶点都有count[V]=0
很好理解,从自己到自己就有一条路,其他的还没有路就设为0,当进行便利时,对每个节点的count++就可以。
4.在一个有权无向图中,如果顶点b到顶点a的最短路径长度是10,顶点c与顶点b之间存在一条长度为3的边。那么下列说法中有几句是正确的?
- c与a的最短路径长度就是13
- c与a的最短路径长度就是7
- c与a的最短路径长度不超过13
- c与a的最短路径不小于7
1和2过于绝对,然后3和4对比第一道判断题,也可以自己在纸上画一下,列出反例。
作业十九 静态查找表与二叉搜索树
题目
1.若二叉搜索树是有N个结点的完全二叉树,则不正确的说法是:
A.所有结点的平均查找效率是O(logN)
B.最小值一定在叶结点上
C.中位值结点在根结点或根的左子树上
D.最大值一定在叶结点上
答案选D。可以辨析一下B C D选项。首先我们从知道,比根节点大的放在右边,比根节点小的放在左边,那么有一种情况就是,比根节点大的放在左边,然后这个根节点又没有右孩子。如下图
很简单的例子,那么这棵树中最大值应该是9,而它不是叶子节点。
那么再看B选项,我们假设最小值不在叶节点,而同时我们不要忘了题目要求,是个完全二叉树,那么也就是说,整棵树的左下角,要么是从左到右有部分节点有孩子,要么都没有,那么根据假设条件,这个最小值不是叶节点,它必须有左孩子,那就说明它不是最小值,与假设相反。所以最小值一定在叶节点。
最后是C选项,依然是完全二叉树的问题,如果是一棵满二叉树,那么中位值肯定在根节点上,因为左右子树节点数相同。而如果右子树不满,那么左子树的节点数多,所以中位数自然在左子树里,很好想。
2.若二叉搜索树是有N个结点的完全二叉树,则不正确的说法是:
A.最小值一定在叶结点上
B.平均查找效率是O(log**N)
C.最大值一定在最后一层
D.中位值结点在根结点或根的左子树上
选C,分析如上题。
3.在有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 查找失败;
本算法与二分查找(折半查找)算法相比,有可能具有更少比较次数的情形是:
A.当x接近数组开头处
B.当x不在数组中
C.当x接近数组结尾处
D.当x位于数组中间位置
选A。这个也分析代码就很好看出来,它从0开始,k每次加3,当第一次A[K]>X的时候,那么肯定就在A[K]到X这三个元素中有一个X,或者X不在数组中,那么很显然,如果X就在序列一开始,那么每次加3,几次就找到了,所以比折半要快。
折半查找判定树
这个有点意思。
1-10,10个数
折半查找
中位数为(5+6)/2=5.5
①折半向上取整
第一层(第一次折半): (1-10)->5.5->6
第二层(第二次折半): 6左孩子(1-5)->3
6右孩子(7-10)->(8+9)/2=8.5->9
第三层(第三次折半): 3左孩子(1-2)->(1+2)/2=1.5->2
3右孩子(4-5)->(4+5)/2=4.5->5
9左孩子(7-8)->(7+8)/2=7.5->8
9右孩子(10)->10
第四层(第四次折半): 2左孩子(1)->1
5左孩子(4)->4
8左孩子(7)->7
②向下取整
理解了这个之后,它的应用也很方便
栗子:对于给定11个数据元素的有序表: (2,3,10,15,20,25,28,29,30,35,40)
采用二分查找,试问:
(1)若查找给定值为20的元素,将依次与表中哪些元素比较?
(2)若查找给定值为26的元素,将依次与哪些元素比较?
(3)假设查找表中每个元素的概率相同,求查找成功时的平均查找长度和查找不成功时的平均查找长度。
(1)
(2)
★这里可以记一个小结论秒杀:
(3)
(4)
Note:关于结点个数选取的问题
然后看作业中题目
下列二叉树中,可能成为折半查找判定树(不含外部结点)的是:
A.
B.
C.
D.
实际上折半查找判定树是一棵二叉排序树,所以它的中序遍历是有序序列,咱们可以把1-10填到每个选项中,然后判断图是否正确的一个方法就是,在一棵树中,要么都选择向上取整,要么都选择向下取整,否则错误。
B选项4、5相加除二向上取整,7、8相加除二向下取整,矛盾。C选项,3、4相加除二向上取整,6、7相加除二向下取整,矛盾。D选项,1、10相加除二向下取整,6、7相加除二向上取整,矛盾。A符合折半查找规则,正确。
作业二十 平衡二叉树和B树
B树基本概念性质
B+树的基本概念性质
题目
1.对一棵平衡二叉树,所有非叶结点的平衡因子都是0,当且仅当该树是完全二叉树。F
平衡因子都是0,说明叶子节点都是齐的,应该是满二叉树,虽然满二叉树是完全二叉树,但是完全二叉树的范围大。
2.若AVL树的深度是6(空树的深度定义为-1),则该树的最少结点数是:
A.13
B.17
C.20
D.33
有个递推公式F(N)=F(N-1)+F(N-2)+1,但是这玩意空树是-1,所以只有根节点的时候是0,也就是说这个深度6实际上是深度7,也就是33
F(1)=1,F(2)=2,F(3)=4,F(4)=7,F(5)=12,F(6)=20,F(7)=33 背过也好
3.B+树不同于B树的特点之一是:
A.能支持顺序查找
B.结点中含有关键字
C.根结点至少有两个分支
D.所有叶结点都在同一层上
观察概念图就可以知道,B+树的叶子节点又被连起来了,所以他是支持顺序查找的。而B树没有。
4.一棵有21个数字的、度为3的B+树最多有 __ 个度为3的结点。
A.1
B.2
C.3
D.4
如图
作业二十一 哈希查找
1.将10个元素散列到100000个单元的哈希表中,是否一定产生冲突?
A.一定会
B.有万分之一的可能会
C.一定不会
D.可能会
这个说不准,不知道散列函数怎么设计,选D可能会
2.对包含N个元素的散列表进行查找,平均查找长度为:
A.O(logN)
B.不确定
C.O*(1)
D.O*(*N)
还是选B 不确定。
3.给定散列表大小为11,散列函数为H(Key)=Key%11。按照线性探测冲突解决策略连续插入散列值相同的4个元素。问:此时该散列表的平均不成功查找次数是多少?
A.4/11
B.1
C.不确定
D.21/11
分析:
区别概念平均成功查找次数和平均不成功查找次数。
平均成功查找次数=每个关键词比较次数之和÷关键词的个数
平均不成功查找次数=每个位置不成功时的比较次数之和÷表长(所谓每个位置不成功时的比较次数就是在除余位置内,每个位置到第一个为空的比较次数,比如此题表长为11,散列函数为Key%11,除余的是11,那么除余位置就是0—10;如果表长为15,但散列函数为Key%13,那么除余位置就是0—12)
明确概念后做题:
连续插入散列值相同的4个元素,我们就假设它的散列值都为0,那么插入后的位置:
其中位置0到第一个为空的位置4的比较次数为5,其余的位置以此类推。
平均不成功查找次数=(5+4+3+2+1+1+1+1+1+1+1)÷ 11 = 21/11
故选D
4.设数字 {4371, 1323, 6173, 4199, 4344, 9679, 1989} 在大小为10的散列表中根据散列函数 h(X)=X%10得到的下标对应为 {1, 3, 4, 9, 5, 0, 2}。那么继续用散列函数 “h(X)=X%表长”实施再散列并用线性探测法解决冲突后,它们的下标变为:
A.1, 3, 4, 9, 5, 0, 2
B.1, 12, 17, 0, 13, 8, 14
C.11, 3, 13, 19, 4, 0, 9
D.1, 12, 9, 13, 20, 19, 11
再散列就是,把表长变为两倍即20,取最近的素数23。然后分别取余就可以了,其实到第三个就可以选出答案了。
5.将元素序列{18,23,11,20,2,7,27,33,42,15}按顺序插入一个初始为空的、大小为11的散列表中。散列函数为:H(Key)=Key%11,采用线性探测法处理冲突。问:当第一次发现有冲突时,散列表的装填因子大约是多少?
A.0.27
B.0.45
C.0.73
D.0.64
装填因子:a=n/m 其中n 为关键字个数,m为表长。
挨个放,第一次遇到冲突时,表里有五个元素,那么就是5/11=0.45
作业二十二 插入类与交换类排序
1.对一组包含10个元素的非递减有序序列,采用直接插入排序排成非递增序列,其可能的比较次数和移动次数分别是:
A.100, 100
B.100, 54
C.54, 63
D.45, 44
他问的是可能的比较次数和移动次数分别是多少,那我们就假设原理就是全部递增的,插入排序后要求全部递减,这样的比较次数应该是最多的,即除了第一个进去的元素,其他的每一次新插入的元素都要跟已经插进去的元素做对比,共1一直加到n次(n=9),即45次。
再次注意,他问的是可能,所有a,b,c都不可能,而44注意也是可能,因为如果中间有两个元素相等,他们比较时是不会移动的,即插入排序的稳定性。
2.设有100个元素的有序序列,如果用二分插入排序再插入一个元素,则最大比较次数是:
A.7
B.10
C.25
D.50
看好是多少个元素,然后就除2就行了,差不多100个7次,1000个10次,上取整。
3.对于序列{ 49,38,65,97,76,13,27,50 },按由小到大进行排序,下面哪一个是初始步长为4的希尔排序法第一趟的结果?
A.13,27,38,49,50,65,76,97
B.49,13,27,50,76,38,65,97
C.49,76,65,13,27,50,97,38
D.97,76,65,50,49,38,27,13
首先注意一点,这个步长是有是指,选择第一个后,再走四步的元素,比如此题中,步长为4则选择的是49和76 .选好之后,比较进行交换,然后再同时到下一个元素,比较再交换。
4.对于7个数进行冒泡排序,需要进行的比较次数为:
A.7
B.14
C.21
D.49
N*(N-1)/2=7*6/2=21
5.采用递归方式对顺序表进行快速排序,下列关于递归次数的叙述中,正确的是:
A.每次划分后,先处理较长的分区可以减少递归次数
B.每次划分后,先处理较短的分区可以减少递归次数
C.递归次数与每次划分后得到的分区处理顺序无关
D.递归次数与初始数据的排列次序无关
选C。反正都是那么多元素,怎么划分都没有关系。
6.在快速排序的一趟划分过程中,当遇到与基准数相等的元素时,如果左右指针都不停止移动,那么当所有元素都相等时,算法的时间复杂度是多少?
A.O*(*logN)
B.O*(*N)
C.O*(*NlogN)
D.O*(*N2)
如果与基准相等,但是左右指针不停止移动,那么说明所有的元素都被划分到一个区间里。这样的话复杂度就是O(N^2) 选D
7.在快速排序的一趟划分过程中,当遇到与基准数相等的元素时,如果左指针停止移动,而右指针在同样情况下却不停止移动,那么当所有元素都相等时,算法的时间复杂度是多少?
A.O*(*logN)
B.O*(*N)
C.O*(*NlogN)
D.O*(*N2)
和上题一样。
作业二十三 快速排序与堆排序
1.对N个记录进行简单选择排序,比较次数和移动次数分别为O(N2)和O(N)。
T 背过
2.有组记录的排序码为{ 46,79,56,38,40,84 },则利用堆排序的方法建立的初始堆为:
A.84,79,56,46,40,38
B.84,56,79,40,46,38
C.84,79,56,38,40,46
D.79,46,56,38,40,80
- 将待排序的数据看作一棵完全二叉树,将第一个数据作为二叉树的根,从左至右依次填充二叉树。
- 对这棵完全二叉树进行调整建堆,即父节点不小于两个子节点为原则。
-
重建堆:将根节点46移出作为待调整节点,然后对根节点的左右子树重建堆。根据得出的树图来看左子树不变,右子树84和56交换位置。
-
-
从84和79选择较大的84同待调整的46做比较,将84上移到根节点。
-
-
将56和待调整的46做比较,56上移到空节点处,46移到56位置处。
-
所以最终的初堆序列为:84,79,56,38,40,46
3.排序过程中,对尚未确定最终位置的所有元素进行一遍处理称为一“趟”。下列序列中,不可能是快速排序第二趟结果的是:
A.5, 2, 16, 12, 28, 60, 32, 72
B.2, 12, 16, 5, 28, 32, 72, 60
C.5, 2, 12, 28, 16, 32, 72, 60
D.2, 16, 5, 28, 12, 60, 32, 72
这个题啥意思呢,我们首先明白一个快速排序划分的时候产生的特点,快速排序如果第一趟确定的值是首尾元素,则第二趟只能确定一个数;如第一趟确定的是中间元素,则第二趟会确定两个元素,在递归实现中表示为,左右分别要递归一次,得出两个值。
这个首尾元素不是说位置,是说这个数组中最小和最大的。什么意思呢,假如第一个枢轴元素选的是最小的或者最大的,那会出现什么情况,所有的元素会被划分到一个区间里,剩下一个空的区间,此时第一次的划分只能确定最小值或最大值,相当于啥也没干,那么第二趟也就只能确定一个数的位置了。
倘若第一次的枢轴选的是个中间元素,那么这个数组必然被划分为两个区间,那么,第二次划分就能确定两个元素的位置。
知道了这个原理之后咱们来看各个选项。
A.5, 2, 16, 12, 28, 60, 32, 72
B.2, 12, 16, 5, 28, 32, 72, 60
C.5, 2, 12, 28, 16, 32, 72, 60
D.2, 16, 5, 28, 12, 60, 32, 72
A选项中,我们看到72位于了最右侧,那说明第一次选的是最大值72,那么这个第二次结束后,这个数组只能有两个元素的位置被确定,那么开始找,只有28的左侧都小于它,右侧都大于它,所以A选项符合要求。
B选项中,我们看到2位于最左侧,大概说明第一次选择了2,那么两次结束后应该只有两个被确定,开始找,发现28和32的位置都被确定了,这与我们的预期不符,但是虽然这个不符合第一个情况,但是如果把它套到第二种情况中,我们可以发现,如果第一次选择的是28,那么第二趟就可以产生2和32的确定位置,或者第一次选择32,同理。所以B选项也是可以的。
D选项中,我们发现2在最左侧,72在最右侧,并且剩下的元素都没有被确定,那么显然符合第一种情况,正确。
最后来看C选项,我们第一眼看去,72没有在最右,2也没有在最左,那么继续找,发现第一个28是正确位置,那么说明,这个数组在两次划分后至少应该是三个位置被确定,继续往后找,发现下一个是32,但是没有了。也就是说,两个位于中间的元素作为枢轴在两次排序后只确定了两个位置,很明显,不符合第一个情况也不符合第二个情况。所以此题选C
这是2019年的408考研题
作业二十四 归并排序和基数排序
1.对N个记录进行归并排序,归并趟数的数量级是O(logN)。
2.对N个记录进行归并排序,空间复杂度为O(N)
3.归并排序的时间复杂度是O(NlogN)
3.归并排序是稳定的。
4.输入105个只有一位数字的整数,可以用O(N)复杂度将其排序的算法是: 基数排序
作业二十四 归并排序和基数排序
1.对N个记录进行归并排序,归并趟数的数量级是O(logN)。
2.对N个记录进行归并排序,空间复杂度为O(N)
3.归并排序的时间复杂度是O(NlogN)
4.归并排序是稳定的。
5.输入105个只有一位数字的整数,可以用O(N)复杂度将其排序的算法是: 基数排序
作业二十五 外部排序和串的模式匹配
最后了,没什么太难的,会找next数组,了解外部排序的基本原理即可
1.设主串的长度为n,模式串的长度为m,则串匹配的KMP算法时间复杂度是( )。
A.O(m)
B.O(n)
C.O(n + m)
D.O(n×m)
选C,这也是KMP最厉害的地方,如果暴力法复杂度将达到n*m
还有个外部排序替换选择法,就是每次拿出一定的数量,找出最小的放到另一个文件中,然后再拿出一个补上,再找出比刚才拿出去的还大的最小的,如此几轮,便有序了。
在外排序中,假设用替换选择法来创建初始的有序段。内存中用到的优先队列规模为5。给定输入序列{5, 20, 26, 46, 31, 25, 16, 51, 17, 28, 1},下列哪组是生成的有序段?
A.run1: 5, 20, 26, 31, 46; run2: 16, 17, 25, 28, 51; run3: 1
B.run1: 5, 20, 25, 26, 31, 46, 51; run2: 1, 16, 17, 28
C.run1:5, 20, 25, 26, 31, 46; run2: 1, 16, 17, 28, 51
D.run1: 5, 20, 26, 31, 46; run2:1, 16, 17, 25, 28, 51