Professional Documents
Culture Documents
计算机科学与技术学科联考
计算机学科专业基础综合试题
一、单项选择题
https://zhuanlan.zhihu.com/p/565209806
data next
1 int sum = 0;
2 for (int i = 1; i < n; i *= 2)
3 for (int j = 0; j < i; j++)
4 sum++;
1
2
A. c B. g C. h D. j
08. 在下图所示的 5 阶 𝐵 树 𝑇 中,删除关键字 260 之后需要进行必要的调
整,得到新的 B 树 𝑇1 。下列选项中,不可能是 𝑇1 根结点中的关键字序列的是 ( )。
11. 对数据进行排序时,若采用直接插入排序而不采用快速排序,则可能的
原因是 ( ) 。
I. 大部分元素已有序 II. 待排序元素数量很少
III. 要求空间复杂度为 𝑂(1) IV. 要求排序算法是稳定的
A. 仅 I、II B. 仅 III、IV C. 仅 I、II、IV D. I、II、III、IV
二、综合应用题
第 41 ∼ 47 小题,共 70 分。
41.(13 分)已知非空二叉树 T 的结点值均为正整数,采用顺序存储方式保
存,数据结构定义如下:
请设计一个尽可能高效的算法,判定一棵采用这种方式存储的二叉树是否为
二叉搜索树,若是,则返回 true,否则,返回 false,要求:
(1) 给出算法的基本设计思想。
(2) 根据设计思想,采用 C 或 C++ 语言描述算法,关键之处给出注释。
42. (10 分) 现有 𝑛(𝑛 > 100000) 个数保存在一维数组 𝑀 中,需要查找 𝑀 中
最小的 10 个数,请回答下列问题。
(1) 设计一个完成上述查找任务的算法,要求平均情况下的比较次数尽可能
少,简单描述其算法思想,不需要程序实现。
(2) 说明你所设计的算法平均情况下的时间复杂度和空间复杂度。
4
2022 全国硕士研究生招生考试计算机学科专业基础试题参考答案
选择题比较简单,除了 08 题合并子结点有拓展。
01.【解析】
答案选 B。
𝑇 (𝑛) = 1 + 2 + … + 2⌊𝑙𝑜𝑔2 (𝑛−1)⌋ = 2⌊𝑙𝑜𝑔2 (𝑛−1)⌋+1 − 1 = 𝑂(𝑛)
另外:⌊𝑙𝑜𝑔2 (𝑛 − 1)⌋ + 1 = ⌈𝑙𝑜𝑔2 𝑛⌉
02.【解析】
答案选 D。
C 选项,如果每个元素入栈后马上出栈,得到的出栈序列与入栈序列完全相
同,所以 C 选项错误
关于 D 选项,如果序列元素全部入栈后再依次出栈,得到的出栈序列与入
栈序列完全相反,所以 D 选项正确。
本题选 D。
03.【解析】
答案选 B。
04.【解析】答案选 C。
满三叉树结点数为 1+3+9+27+81+X=243, X=122。所以高度最少 6 层。
05.【解析】答案选 D。
等长编码的特点是每个字符的编码长度相同。下图的上为等长编码,下为哈
夫曼编码。选项 A,B 明显错误,C 很明显也错误。
5
06.【解析】答案选 D。
若 𝐺 一定是连通的,则满足
(|𝑉 | − 1)(|𝑉 | − 2)
|𝐸| ≥ +1
2
即先分成两个连通分量,一个顶点数量为 |𝑉 | − 1 ,结点之间两两相连,边数为
(|𝑉 | − 1)(|𝑉 | − 2)/2 ,另一个为一个顶点,边数为 0 ,最后连接两个连通分量,需
要 1 条边。所以 A,B 选项错误。
最小连通子图时 |𝑉 | = |𝐸| − 1,所以 C 错误。
07.【解析】答案选 B。
09.【解析】答案选 D。
10.【解析】答案选 A。
B 选项错误,这是快速排序的目标。
C 选项错误,这不是归并操作。
D 选项错误,这是快速排序的性质。
本题选 A。
11.【解析】答案选 D。
41.【解析】
如果一个结点编号为 i,则其左孩子为 2*i+1,右孩子为 2*i+2。
方法一:
设计思想:采用递归,使用范围检查是否为二叉树搜索。
检查一颗树是否为二叉查找树,不妨设值范围在 [lower,upper] 之间。可以执
行下面三步:
(1) 根结点的值 root_value 应该在 [lower,upper] 之间
(2) 左子树的值应该在 [lower,root_value] 之间
(3) 右子树的值应该在 [root_value, upper] 之间
最早值区间为 [𝐼𝑁𝑇 _𝑀𝐼𝑁, 𝐼𝑁𝑇 _𝑀𝐴𝑋],表示所有的有效整数。
#include <iostream>
#include <climits>
using namespace std;
7
//方案一
bool helper(SqBiTree &T, int i, int lower, int upper)
{
//cout << i << ' ' << T.SqBiTNode[i] << endl;
if(i >= T.ELemNum || T.SqBiTNode[i] == −1) { // 越界或者为空
结点
return true;
}
if(T.SqBiTNode[i] <= lower || T.SqBiTNode[i] >= upper) {
return false;
}
return helper(T, 2 * i + 1, lower, T.SqBiTNode[i]) &&
helper(T, 2 * i + 2, T.SqBiTNode[i], upper);
}
//方案二
int prior = INT_MIN;
//检查根结点为id的树是否为BST
bool isValidBST2(SqBiTree &T, int id)
{
if(id >= T.ELemNum || T.SqBiTNode[id] == −1) { //越界或者为
空结点
return true;
}
8
if(!isValidBST2(T, 2 * id + 1 ) )
return false;
if(T.SqBiTNode[id] < prior ) //不符合中序遍历有序
return false;
prior = T.SqBiTNode[id]; //修改prev值为当前结点值
return isValidBST2(T, 2 * id + 2 );
}
int main()
{
SqBiTree T;
CreateTree(T);
//cout << isValidBST(T);
cout << isValidBST2(T, 0);
}
/*
合法的BST
10
40 25 60 −1 30 −1 80 −1 −1 27
7
40 25 60 23 30 −1 80
非BST
11
40 50 60 −1 30 −1 −1 −1 −1 −1 35
7
40 25 60 27 30 −1 80
9
*/
复杂度分析
假定二叉树的结点个数为 n。在递归调用的时候二叉树的每个结点被访问一
次,时间复杂度为 O(n) 。最坏情况下二叉树为一条链,递归最深达到 n 层,故最
坏情况下空间复杂度为 O(n)。
方法二:二叉树搜索的中序遍历是有序的,所以在中序遍历时,可以保存前
驱节点值,如果当前节点小于前驱节点,则这棵树不是 BST。
复杂度分析
假定二叉树的结点个数为 n。在递归调用的时候二叉树的每个结点被访问一
次,时间复杂度为 O(n) 。最坏情况下二叉树为一条链,递归最深达到 n 层,故最
坏情况下空间复杂度为 O(n)。
42.【解析】
这实际是 top K 问题。
方法一: 利用选择排序思想。
遍历 𝐴[1 ∶ 𝑛] ,找到最小值交换到 𝐴[1] 。
遍历 𝐴[2 ∶ 𝑛] ,找到最小值交换到 𝐴[2] 。
遍历 𝐴[3 ∶ 𝑛] ,找到最小值交换到 𝐴[3] 。
遍历 𝐴[4 ∶ 𝑛] ,找到最小值交换到 𝐴[4] 。
遍历 𝐴[5 ∶ 𝑛] ,找到最小值交换到 𝐴[5] 。
遍历 𝐴[6 ∶ 𝑛] ,找到最小值交换到 𝐴[6] 。
遍历 𝐴[7 ∶ 𝑛] ,找到最小值交换到 𝐴[7] 。
遍历 𝐴[8 ∶ 𝑛] ,找到最小值交换到 𝐴[8] 。
遍历 𝐴[9 ∶ 𝑛] ,找到最小值交换到 𝐴[9] 。
遍历 𝐴[10 ∶ 𝑛] ,找到最小值交换到 𝐴[10] 。
此时 𝐴[1 ∶ 10] 保存的就是排序好的最小的 10 个数。
复杂度分析:
- 时间复杂度: 𝑂(𝑛) ,需要遍历 10 次数組。
- 空间复杂度:𝑂(1) ,中间过程额外需要常数个变量。
方法二: 堆 (堆排序思想),该方法由于方法一。
先用 𝐴[1 ∶ 10] 原地建立大顶堆 (注意:这里不能用小顶堆),遍历 𝐴[11 ∶ 𝑛]
,每个元素 𝐴[𝑖] 逐一和堆顶元素 𝐴[1] 进行比较,其中 11 ≤ 𝑖 ≤ 𝑛 ,如果 𝐴[𝑖] 大
于等于堆顶元素 𝐵[1] ,不进行任何操作,如果该元㚠小于堆顶元素 𝐴[1] ,那么
就删除堆顶元素,将该元素放入堆顶,即令 𝐴[1] = 𝐴[𝑖] ,然后将 𝐴[1 ∶ 10] 重新
调整为大顶堆。最后堆 𝐴[1 ∶ 10] 中留存的元素即为最小的 10 个数。
复杂度分析:
10