一、单选题(题数:4,共6.0分)
1、下列关于树的叙述正确的是()
A、只有一个叶子结点
B、最多只有一个根结点
C、树不是层次结构的数据结构
D、某结点的孩子结点必须是叶子结点
正选【B】
2、2K层满二叉树上最多有()个叶子结点
A、2^K
B、2^(K-1)
C、(2^K)-1
D、(2^K)+1
正选【C】
解析:高为h的满二叉树共有(2^h)-1个结点
3、含有n个顶点的图,最多可能含有边的条数为()
A、n*(n-1)
B、n*(n-1)/2
C、n2
D、2n
正选【B】对于每个顶点,我们可以将其与其他n-1个顶点相连。但由于是无向图,连接顶点A到顶点B的边与连接顶点B到顶点A的边是等效的,所以只需考虑其中一种情况。因此,每顶点最多可以与n-1个其他顶点相连。
所以,需要除以2来消除重复计算。
所以每个最多可能的边的条数为(n-1)/2,即选项B。n*(n-1)/2。
4、我们常说某排序算法是稳定的是指()
A、该算法排序后值相同的元素能保持排序前的前后相对位置不变
B、该算法对于不同的初始序列的效果相同,表现稳定
C、该算法的代码稳定
D、该算法不需要在内外存之间进行交换排序数据
正选【A】
解析:排序算法是稳定的是指:如果排序前的两个元素A和B,它们的值相等,且A在B之前,那么在排序后,A仍然会在B之前
二、判断题(题数:6,共6.0分)
1完整二叉树一定是满二叉树。 ()
正选【错】
解析:
[满二叉树]:
1.只有最后一层有叶子结点
2.不存在度为1的结点
3.同完全二叉树第3条
[完全二叉树]:
1.只有最后两层可能有叶子结点;
2.最多只有一个度为1的结点;
3.按层序从1开始排序i的左节点为2i,右节点为2i+1,父节点为i/2
4.i<=n/2为分支结点,i>=n/2为叶子结点
(如果某节点只有一个孩子那么一定是左孩子)
2排序所花的时间与给出序列的顺序相关。()
正选【对】
解析:
纯说时间而非时间复杂度的话,此题是对的。
绝大多数排序算法的时间复杂度是基于输入序列的大小而确定的,而不是基于给出序列的顺序。排序算法的性能可以受到输入序列的顺序的影响,但这并不改变排序算法的时间复杂度。
扩展:
对于冒泡排序和插入排序这样的比较排序算法,如果给出的序列已经是有序的,它们的时间复杂度将会变得较低。因为在有序序列中,不需要进行太多的元素交换或移动。
但对于快速排序这样的递归排序算法,如果给出的序列是已经有序或接近有序的,且选择的主元(pivot)不合适,它的性能可能会下降,导致递归树不平衡
3. 大根堆可以很好地完成排序,小根堆则不能()
正选【错】
解析:
大根堆和小根堆都是堆数据结构的一种变种,它们在排序中的作用是相反的。
大根堆是一种满足父节点值大于等于其子节点值的特性的堆。在大根堆中,堆顶元素是最大的元素。通过不断将堆顶元素与最后一个元素交换,并重新调整堆,可以将堆中的元素逐步排序,最终得到一个按照从大到小排列的序列。【大根堆可以用于完成降序排序】
小根堆是一种满足父节点值小于等于其子节点值的特性的堆。在小根堆中,堆顶元素是最小的元素。通过不断将堆顶元素与最后一个元素交换,并重新调整堆,可以将堆中的元素逐步排序,最终得到一个按照从小到大排列的序列。【小根堆可以用于完成升序排序】
无论是大根堆还是小根堆,在排序中都可以起到很好的作用,只是得到的排序结果的顺序是相反的。
4.最小生成树的Prim算法更适合于稠密图()
正选【对】
Prim算法是一种用于构建最小生成树的贪心算法。在Prim算法中,从一个起始顶点开始,逐步扩展最小生成树的边集合,直到包含所有顶点为止。
在稠密图中,顶点之间的边比较多,因此Prim算法更适合。这是因为Prim算法的主要开销是在不断选择最小权值边的过程中,而在稠密图中,每个顶点之间都有边,所以Prim算法可以更快地找到最小权值的边,从而更高效地构建最小生成树。
扩展:
相比之下,在稀疏图中,顶点之间的边相对较少,而Prim算法需要遍历顶点并检查边的权值,这可能导致较多的不必要计算。在这种情况下,使用Kruskal算法(另一种常用的最小生成树算法)可能更为高效,Kruskal算法以边为基础,而不需要遍历顶点。
5.平衡排序二叉树的查找效率非常高,为O(log2n)()
正选:【对】
在平衡排序二叉树中进行查找时,每次比较都可以排除树中的一半节点,查找的时间复杂度是O(log₂n)。在最坏情况下的查找效率为O(log₂n),其中n是树中节点的数量。
【平衡排序二叉树】,是一种自平衡的二叉搜索树,例如红黑树和AVL树。在平衡排序二叉树中,每个节点的左子树和右子树的高度差不超过1,以保持树的平衡。(简单来说就是使一棵树长得矮又宽,实现更高效的搜索)
6 AOV网络的拓扑排序序列不唯一()
正选:【对】
因为在一个AOV网络中,可能存在多个没有依赖关系或者依赖关系相同的活动,这些活动可以互相交换位置而不影响拓扑排序的结果
例如:
A --> B --> C
拓扑排序的结果可以是:A, B, C;也可以是:B, A, C。
这两种序列都满足A依赖于B,B依赖于C的关系
三、填空题(题数:5,共30分) *此题型为主观题,需要教师打分
1.对一组数据{2,12,16,88,5,10}进行冒泡升序排序,则第三趟排序的后的序列是
答案【2,5,10,12,16,88】
冒泡: 比较相邻的两个元素,如果前面的元素大于后面的元素,则交换它们。
步骤:
第一趟排序:{2,12,16,5,10,88}
第二趟排序: {2,12,5,10,16,88}
第三趟排序: {2,5,10,12,16,88}
2.对序列{265,301,751,129,937,863}进行降序插入排序,则第二趟排序收集后的序列是(2.0分)
答案【751,301,265,129,937,863】
第一趟排序: 将第二个元素301插入到已排序的序列{265}中,得到{301,265}。
第二趟排序: 将第三个元素751插入到已排序的序列{301,265}中,得到{751,301,265}。
第二趟排序收集后的序列是{751,301,265}。
3.下面是一趟降序插入排序算法的代码段,认真阅读代码段,完成(1)-(5)的算法填空,其中r[0]为附加的监视哨。
void InsSort( RecordType r[], int length)
{
int i; //控制插入的次数
int j; // 控制插入的位置
for (i=2; i<___(1)____; i++)
{
r[0]=____(2)____; // 给监视哨赋值等插入元素
j= i-1;
while (r[0].key___(3)____ r[j].key ) // 搜索等插入位置
{
r[j+1]=____(4)_____; // 向后移动一个元素位置
j--;
}
r[j+1]=___(5)_____; // 插入等插入元素
}
} /* InsSort */
答案:
(1)length
(2)r[i]
(3)>
(4)r[j]
(5)r[0]
算法思想:
1)传入原始数组以及数字长度
2)r[0]作为哨兵,用来存放下一个需要插入的元素
3)开始,使哨兵=数组中第二个元素
4)拿哨兵(数组第二个元素)去比较数组中第一个元素
5)如果哨兵值大于此元素,就将小的放后面(因为是降序插入)。假如此时哨兵大于数组第一个元素,则小的元素放到后面,即r[2]=r[1]
6)使 j-1,然后继续循环判断哨兵是否大于再前面的元素,若大就还把小的放后面
7)while循环判断结束,此时将哨兵存的元素也插入序列,r[j+1]=r[0](第6步j-1此时+1回到哨兵原位置进行插入)
8)for循环继续将下一个元素放入哨兵 继续进行while循环判断依次插入。以此类推
【快速排序解析待更新】
4下面是快速排序算法,根据注释阅读代码段,在空行处填写相应的程序代码。
// 快速划分函数
int QKPass(RecordType r[], int left,int right);
/*对记录数组r[low..high]用快速排序算法进行排序*/
void QKSort (RecordType r[], int low, int high )
{
if(low<_______)
{
pos=QKPass(r, ____, high);
QKSort(r, low, ____);
QKSort(r, ____, high);
}
}
答案:
high
low
pos-1
pos+1
5下面程序段是二叉树先序遍历递归算法,请在下划线处填上正确的语句。
typedef struct Node
{
DataType _______;
struct Node *LChild;
struct Node *RChild;
} BiTNode, *BiTree;
/*先序遍历二叉树, root为指向二叉树根结点的指针*/
void PreOrder(BiTree root)
{
if (_______)
{
Visit(root ->data); /*访问根结点*/
PreOrder(______); /*先序遍历左子树*/
PreOrder(______); /*先序遍历右子树*/
}
}
答案:
data
root! =NULL
root ->LChild
root ->RChild
解析:
第一空:二叉树的结构,一个存数据,两个存左右孩子,所以此空填 data
第二空:if判断该树是否为空如果为空的话就不用遍历了,所以填root!=NULL
第三、四空:因为是先序遍历所以,并且是递归算法,先访问根结点然后依次访问左右子树,所以填root ->LChild;root ->RChild
四、资料题(题数:5,共60.0分) *此题型为主观题,需要教师打分
1.某二叉树的先序遍历是ABCDEFGHIJ中序遍历是BCDAFEHJIG。
1)根据给出的两个遍历画出该二叉树;(9分)
2)写出该二叉树的后续遍历;(2分)
3)把该二叉树转换为树或森林。(9分)
2.一份用于某敏感数据网络传输的电文由7个字符A、B、C、D、E、F、G组成,经统计各字符在电文中出现的概率分别为:0.2,0.02, 0.1, 0.03, 0.3, 0.25, 0.1,请给该字符集设计一套平均码长最短的编码方案。要求如下:
(1)要求给出设计编码过程所使用的哈夫曼树(5分);
(2)给出7个字母的编码(3分);
(3) 计算编码后的报文长度。(2分)
编码方案:
字符
编码
概率
码长
A
00
0.2
2
B
01000
0.02
5
C
0101
0.1
4
D
01001
0.03
5
E
11
0.3
2
F
01
0.25
2
G
011
0.1
3
平均码长 = 0.2*2 + 0.02*5+0.1*4+0.03*5+0.3*2+0.25*2+0.1*3
=0.4+0.1+0.4+0.15+0.6+0.5+0.3
=2.45
3.已知一组关键字(45,36,56,28,42,70,43,18,98)哈希表长度为10,哈希函数为H(key)=key%11,则用线性探测再散列法处理冲突。
1)详细写出地址计算过程及解决冲突的过程(3分);
2)构造哈希表(用表格表示)(3分);
3)手工计算等概率情况下的ASLsuccess的平均查找长度(2分)。
4)手工计算等概率情况下的ALSunsuccess的平均查找长度(2分)。(10.0分)
(1):
Hash(45)=45%11=1
Hash(36)=36%11=3
Hash(56)=56%11=1 —>2
Hash(28)=28%11=6
Hash(42)=42%11=9
Hash(70)=70%11=4
Hash(43)=43%11=10 —>0
Hash(18)=18%11=7
Hash(98)=98%11=10 —>0 —>1 —>2 —>3 —>4 —>5
(2):
0
1
2
3
4
5
6
7
8
9
43
45
56
36
70
98
28
18
42
2
1
2
1
1
6
1
1
1
(3):
ASLsuccess=1/9*(1*6 + 2*2 + 1*6)=16/9
(4):
ASLunsuccess=1/11*(1+10+9+8+7+6+5+4+3+2)=57/11
=====================================================================
【解析】:
解题思路:
(1)
拿每个关键字带入到哈希函数进行取余运算得到每个的余数,若得到的余数与之前的相同则认为发生了冲突,当发生冲突时,使用线性探测再散列法进行解决,即探测下一个位置,例如:关键字 56 冲突,继续探测下一个位置: H'(56) = (H(56) + 1) % 10 = (1 + 1) % 10 = 2
同样关键字98连续发生冲突进行一连串的探测后得到5作为地址
(2)
已知一组关键字(45,36,56,28,42,70,43,18,98)哈希表长度为10
根据地址计算和解决冲突的过程得出上面的哈希表,
第一行是0-9作为哈希表长,即10;
第二行是这组关键字,对应算出的哈希地址填入相应的位置,在填写过程中注意,经过线性探测再散列法的处理,关键字 56 和关键字 98 在哈希表中找到了新的位置。
第三行通俗来讲就是能几次找到这个关键字,能一下找到就是1,被冲突处理过n次就是n;
(3)
ASLsuccess(平均成功查找长度)表示在关键字等概率的情况下,进行成功查找的平均查找长度。
关键字数量为 9,哈希表长度为 10,因此填充因子为 9/10 = 0.9。
由于哈希函数为 H(key) = key % 11,即使用除余法,关键字的分布是等概率的。
根据线性探测再散列法,成功查找的平均查找长度 ASLsuccess 的计算公式为: ASLsuccess = (1/9) * (1 * 6 + 2 * 2 + 1 * 6) = 16/9
其中,1/9 是关键字出现的概率;1 * 6 表示成功查找的关键字在哈希表中找到时的查找长度为 1,共有 6 个关键字; 2 * 2 表示成功查找的关键字经过一次线性探测后在哈希表中找到时的查找长度为 2,共有 2 个关键字; 1 * 6 表示成功查找的关键字经过两次线性探测后在哈希表中找到时的查找长度为 6,共有 1 个关键字。
所以,等概率情况下的 ASLsuccess 的平均查找长度为 16/9。
ASLunsuccess(平均不成功查找长度)表示在关键字等概率的情况下,进行不成功查找的平均查找长度。
ASLunsuccess=1/11*(1+10+9+8+7+6+5+4+3+2)=57/11
其中,1/11 是关键字未被查找到的概率,表示每个关键字的不成功查找的概率,也即每个关键字的查找长度的权重。
根据线性探测再散列法,如果关键字未被查找到,需要遍历哈希表的所有位置,即需要进行 1 次初始查找和 10 次线性探测。
括号内的值是表示每次线性探测所经过的位置的个数,即在不成功查找时的查找长度。
4.根据Prim算法求解下图的最小生成树,假设该图使用邻接矩阵存储,请写出该邻接矩阵(2分),并填写表格(6分),画出最小生成树(2分)。(10分)
邻接矩阵:0
a
b
c
d
e
f
g
a
∞
19
∞
∞
14
∞
18
b
19
∞
5
7
12
∞
∞
c
∞
5
∞
3
∞
∞
∞
d
∞
7
3
∞
8
21
∞
e
14
12
∞
8
∞
∞
16
f
∞
∞
∞
21
∞
∞
27
g
18
∞
∞
∞
16
27
∞
表格:最小生成树:
i
closeedge[i]
0
a
1
b
2
c
3
d
4
e
5
f
6
g
U
V-U
e
k
(u,v)
adjvex
lowcost
0
a
19
∞
∞
a
14
∞
a
18
{a}
{b,c,d,e,f,g}
1
4
(a,e)
adjvex
lowcost
0
b
12
∞
e
8
0
∞
e
16
{a,e}
{b,c,d,f,g}
2
3
(d,e)
adjvex
lowcost
0
d
7
d
3
0
0
d
21
e
16
{a,d,e}
{b,c,f,g}
3
2
(c,d)
adjvex
lowcost
0
c
5
0
0
0
d
21
e
16
{a,c,d,e}
{b,f,g}
4
1
(b,c)
adjvex
lowcost
0
0
0
0
0
d
21
e
16
{a,b,c,d,e}
{f,g}
5
6
(e,g)
adjvex
lowcost
0
0
0
0
0
d
21
0
{a,b,c,d,e,g}
{f}
6
5
(d,f)
adjvex
lowcost
0
0
0
0
0
0
0
{a,b,c,d,e,f,g}
{}
5、对下图所示的AOE网进行分析,找出一条关键路径
顶点i | ve(i) | vl(i) | 活动ai | e(i) | l(i) | l(i)-e(i) |
0 | a1 | |||||
1 | a2 | |||||
2 | a3 | |||||
3 | a4 | |||||
4 | a5 | |||||
5 | a6 | |||||
6 | a7 | |||||
7 | a8 | |||||
8 | a9 | |||||
a10 | ||||||
a11 |
答:
顶点i
ve(i)
vl(i)
活动ai
e(i)
l(i)
l(i)-e(i)
0
0
0
a1
0
0
0
1
6
6
a2
0
2
2
2
4
6
a3
0
3
3
3
5
8
a4
6
6
0
4
7
7
a5
4
6
2
5
7
10
a6
5
8
3
6
16
16
a7
7
7
0
7
14
14
a8
7
7
0
8
18
18
a9
7
10
3
a10
16
16
0
a11
14
14
0
关键路径:a1, a4,a7,a10
或a1, a4, a8, a11