GESP6 · 2024年3月真题

客观题逐题精讲

15 道单选 + 10 道判断。每题保留题干、选项、答案、考点、分步推导和易错提醒,适合投影讲评与课后复习。

一、考点地图

动态规划的基本特征1 题
动态规划应用(不相邻子序列最大和)1 题
动态规划状态转移方程1 题
队列的特性1 题
二叉树遍历推导1 题
二叉搜索树(BST)的性质1 题
格雷码编码规律1 题
广度优先搜索(BFS)层序遍历1 题
哈夫曼编码的前缀性质1 题
哈夫曼编码性质1 题
哈夫曼树定义1 题
哈夫曼树构建1 题

二、单选题逐题讲

单选题 1哈夫曼树构建

在构建哈夫曼树时,每次应该选择()合并。

  1. A最小权值的节点
  2. B最大权值的节点
  3. C随机节点
  4. D深度最深的节点
展开解析
答案:A
哈夫曼树构建
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 哈夫曼树构建采用贪心策略,每次从当前森林中选取两棵根节点权值最小的树作为左右子树合并,新根节点权值为两者之和。
易错点:误选权值最大或深度最深的节点。
单选题 2面向对象编程基本特征

面向对象的编程思想主要包括以下哪些原则()?

  1. A贪心、动态规划、回溯
  2. B并发、并行、异步
  3. C递归、循环、分治
  4. D封装、继承、多态
展开解析
答案:D
面向对象编程基本特征
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 面向对象编程(OOP)的三大核心原则是封装(隐藏细节)、继承(代码复用)和多态(同一接口多种实现)。
易错点:将贪心、分治等算法设计思想误认为面向对象原则。
单选题 3队列的特性

在队列中,元素的添加和删除是按照()原则进行的。

  1. A先进先出
  2. B先进后出
  3. C最小值先出
  4. D随机进出
展开解析
答案:A
队列的特性
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 队列(Queue)是一种先进先出(First-In-First-Out, FIFO)的受限线性表,只允许在队尾插入,在队头删除。
易错点:混淆队列与栈(先进后出)的操作原则。
单选题 4C++ 构造函数与对象成员访问

给定一个简单的类定义如下,()语句在类的外部正确地创建了一个 Circle 对象并调用了 getArea 函数?

class Circle {
    private:
        double radius;
    public:
        Circle(double r) : radius(r) {}
        double getArea() {
            return 3.14 * radius * radius;
        }
    };
  1. ACircle c = Circle(5.0); c.getArea(c);
  2. BCircle c(5.0); getArea(c);
  3. CCircle c = new Circle(5.0); c.getArea();
  4. DCircle c(5.0); c.getArea();
展开解析
答案:D
C++ 构造函数与对象成员访问
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. C++ 中 Circle c(5.0) 调用有参构造函数在栈上创建对象,c.getArea() 通过对象名点号访问成员函数。
  2. A、B项调用语法错误,C项 new 返回指针,需用 -> 访问。
易错点:混淆栈对象(用.访问)与堆指针(用->访问)的成员调用方式。
单选题 5二叉搜索树(BST)的性质

以下代码希望能在一棵二叉排序树中搜索特定的值,请在横线处填入(),使其能正确实现相应功能。

TreeNode* search(TreeNode* root, int target) {
    if (root == NULL || root->val == target) {
        return root;
    }
    if (target < root->val) {
        return search(root->left, target);
    } else {
        return search(root->right, target);
    }
}
  1. Atarget < root->left
  2. Btarget < root->val
  3. Ctarget > root->val
  4. Dtarget > root->left
展开解析
答案:B
二叉搜索树(BST)的性质
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 二叉排序树定义为:左子树所有节点值小于根,右子树所有节点值大于根。
  2. target 小于当前 root->val,根据性质应递归搜索左子树。
易错点:混淆二叉搜索树中左右子树与根节点的大小逻辑关系。
单选题 6格雷码编码规律

3位格雷编码的正确顺序是()。

  1. A000, 001, 010, 011, 100, 101, 110, 111
  2. B000, 001, 011, 010, 110, 111, 101, 100
  3. C000, 010, 001, 011, 100, 110, 101, 111
  4. D000, 010, 110, 100, 111, 101, 011, 001
展开解析
答案:B
格雷码编码规律
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 格雷码相邻编码之间只有一位二进制位不同。
  2. 3位格雷码序列依次为:000, 001, 011, 010, 110, 111, 101, 100。
  3. A项为普通二进制顺序。
易错点:误将二进制递增顺序(0,1,2,3...)当作格雷码顺序。
单选题 7动态规划应用(不相邻子序列最大和)

以下动态规划算法的含义与目的是()。

int function(vector<int>& nums) {
    int n = nums.size();
    if (n == 0)
        return 0;
    if (n == 1)
        return nums[0];
    vector<int> dp(n, 0);
    dp[0] = nums[0];
    dp[1] = max(nums[0], nums[1]);
    for (int i = 2; i < n; ++i) {
        dp[i] = max(dp[i - 1], nums[i] + dp[i - 2]);
    }
    return dp[n - 1];
}
  1. A计算数组 nums 中的所有元素的和
  2. B计算数组 nums 中相邻元素的最大和
  3. C计算数组 nums 中不相邻元素的最大和
  4. D计算数组 nums 中的最小元素
展开解析
答案:C
动态规划应用(不相邻子序列最大和)
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 代码中的状态转移方程 dp[i] = max(dp[i-1], nums[i] + dp[i-2]) 表示第 i 位取舍逻辑:若取 nums[i] 则不能取前一位,故加 dp[i-2]。
  2. 这正是计算不相邻元素最大和的经典模型。
易错点:误认为是求连续子数组最大和或所有元素之和。
单选题 8广度优先搜索(BFS)层序遍历

阅读以下广度优先搜索的代码: 使用以上算法遍历以下这棵树,可能的输出是()。

void bfs(TreeNode* root) {
    if (root == NULL) {
        return;
    }
    queue<TreeNode*> q;
    q.push(root);
    while (!q.empty()) {
        TreeNode* current = q.front();
        q.pop();
        cout << current->val << " ";
        if (current->left) {
            q.push(current->left);
        }
        if (current->right) {
            q.push(current->right);
        }
    }
}
1
/ \
2 3
/ \
8 9 6
/ \
4 5 7
/ \
10 11
  1. A1 2 8 9 4 5 3 6 7 10 11
  2. B1 2 3 4 5 6 7 8 9 10 11
  3. C1 2 3 8 9 6 4 5 7 10 11
  4. D1 2 3 8 9 4 5 6 7 10 11
展开解析
答案:C
广度优先搜索(BFS)层序遍历
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. BFS 按层访问。
  2. 第一层:1;
  3. 第二层:2,3;
  4. 第三层:2的孩子8,9,3的孩子6;
  5. 第四层:8的孩子4,5,6的孩子7;
  6. 第五层:4的孩子10,11。
  7. 拼合即得 1 2 3 8 9 6 4 5 7 10 11。
易错点:误将 BFS 过程混淆为 DFS(深度优先搜索)的先序或中序遍历。
单选题 9栈(Stack)的操作

给定一个空栈,执行以下操作序列: 操作序列: push(1), push(2), push(3), pop(), pop(), push(4), push(5), pop() 最终栈中的元素是()。

  1. A1,2
  2. B1,4,5
  3. C1,2,5
  4. D1,4
展开解析
答案:D
栈(Stack)的操作
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 过程模拟:push(1)->[1];
  2. push(2)->[1,2];
  3. push(3)->[1,2,3];
  4. pop()->[1,2];
  5. pop()->[1];
  6. push(4)->[1,4];
  7. push(5)->[1,4,5];
  8. pop()->[1,4]。
  9. 最终栈内剩余 1,4。
易错点:混淆栈的后进先出规则,导致 pop 操作后剩余元素计算错误。
单选题 10完全二叉树性质计算

一个有 124 个叶子节点的完全二叉树,最多有()个结点。

  1. A247
  2. B248
  3. C249
  4. D250
展开解析
答案:B
完全二叉树性质计算
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 二叉树中叶子节点数 n_0 = n_2 + 1,故 n_2 = 123。
  2. 完全二叉树总节点 n = n_0 + n_1 + n_2 = 124 + n_1 + 123 = 247 + n_1。
  3. 由于 n_1 只能为 0 或 1,求最多结点即 n_1=1,总数为 248。
易错点:忘记计算完全二叉树中可能存在的度为 1 的节点(n_1)。
单选题 11动态规划的基本特征

在求解最优化问题时,动态规划常常涉及到两个重要性质,即最优子结构和()。

  1. A重叠子问题
  2. B分治法
  3. C贪心策略
  4. D回溯算法
展开解析
答案:A
动态规划的基本特征
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 动态规划有两个必要性质:最优子结构(问题的最优解包含其子问题的最优解)和重叠子问题(子问题被多次重复计算)。
易错点:将分治策略(通常子问题的解不被多次使用)或贪心策略误认为动态规划特有的“重叠子问题”性质。
单选题 12二叉树遍历推导

若一棵二叉树的先序遍历为:A, B, D, E, C, F、中序遍历为:D, B, E, A, F, C,它的后序遍历为()。

  1. AD, E, B, F, C, A
  2. BE, D, B, F, C, A
  3. CD, E, B, C, F, A
  4. DE, D, B, C, F, A
展开解析
答案:A
二叉树遍历推导
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 由先序知 A 为根。
  2. 由中序知左子树 (D,B,E),右子树 (F,C)。
  3. 递归:左子树先序 BDE,中序 DBE,知 B 为根且 D 左 E 右;
  4. 右子树先序 CF,中序 FC,知 C 为根且 F 为左。
  5. 结构:A(B(D,E), C(F,空))。
  6. 后序:D, E, B, F, C, A。
易错点:在推导左右子树结构时,根节点与左右节点的相对位置判断错误。
单选题 13筛法复杂度分析

线性筛法与埃氏筛法相比的优势是()。

  1. A更容易实现
  2. B更节省内存
  3. C更快速
  4. D更准确
展开解析
答案:C
筛法复杂度分析
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 埃氏筛法会对同一个合数进行多次标记(如 6 被 2 和 3 分别标记),而线性筛通过限制只用最小质因子标记合数,保证每个数只被处理一次,时间复杂度为 O(N),效率更高。
易错点:误认为线性筛比埃氏筛更节省空间(实际上线性筛需要额外数组记录最小质因子)。
单选题 14欧几里得算法(辗转相除法)

以下代码使用了辗转相除法求解最大公因数,请在横线处填入(),使其能正确实现相应功能。

int gcd(int a, int b) {
    while (b != 0) {
        ___
    }
    return a;
}
  1. Aint temp = b; b = a / b; a = temp;
  2. Bint temp = a; a = b / a; b = temp;
  3. Cint temp = b; b = a % b; a = temp;
  4. Db = a % b; a = b;
展开解析
答案:C
欧几里得算法(辗转相除法)
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 辗转相除法核心逻辑为 gcd(a, b) = gcd(b, a % b)
  2. 循环中需利用中间变量 temp 暂存 b,然后将 b 更新为 a % b,再将暂存的 temp 赋给 a
易错点:混淆变量赋值顺序或误用除号(/)代替求余符号(%)。
单选题 15链表反转算法

下面的代码片段用于反转单链表,请进行()修改,使其能正确实现相应功能。

ListNode* reverseLinkedList(ListNode* head) {
    ListNode* prev = nullptr;
    ListNode* current = head;
    while (current != nullptr) {
        ListNode* next = current->next;
        current->next = next;
        prev = current;
        current = next;
    }
    return prev;
}
  1. Acurrent->next = next; 应该改为 current->next = prev;
  2. BListNode* next = current->next; 应该改为 ListNode* next = prev->next;
  3. Ccurrent != nullptr 应该改为 current->next != nullptr
  4. DListNode* prev = nullptr; 应该改为 ListNode* prev = head;
展开解析
答案:A
链表反转算法
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 反转单链表的核心是让当前节点的 next 指向前驱 prev
  2. 代码中 current->next = next 维持了原序,应修正为 current->next = prev 以实现指针调头。
易错点:对链表节点修改顺序理解有误,导致循环中指针丢失或未实现反向链接。

三、判断题逐题讲

判断题 1哈夫曼树定义

哈夫曼树是一种二叉树。

  1. 正确正确
  2. 错误错误
展开解析
答案:正确
哈夫曼树定义
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 哈夫曼树又称最优二叉树,是一种带权路径长度最短的特殊二叉树。
易错点:误以为哈夫曼树是多叉树。
判断题 2动态规划状态转移方程

在动态规划中,状态转移方程的作用是定义状态之间的关系。

  1. 正确正确
  2. 错误错误
展开解析
答案:正确
动态规划状态转移方程
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 状态转移方程是动态规划的核心,它描述了如何由已知子问题的状态推导出当前问题的状态。
易错点:认为状态转移方程只用于定义初始边界。
判断题 3面向对象继承概念

继承是将已有类的属性和方法引入新类的过程。

  1. 正确正确
  2. 错误错误
展开解析
答案:正确
面向对象继承概念
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 继承允许子类获得基类的公有和保护成员,从而实现代码的扩展和复用。
易错点:无。
判断题 4完全二叉树定义

完全二叉树的任意一层都可以不满。

  1. 正确正确
  2. 错误错误
展开解析
答案:错误
完全二叉树定义
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 完全二叉树要求除了最后一层,其他每一层都必须是满的,且最后一层的节点靠左对齐。
易错点:混淆完全二叉树与普通二叉树的层级结构要求。
判断题 5链表删除操作

删除单向链表中的节点,只需知道待删除节点的地址即可,无需访问前一个节点。

  1. 正确正确
  2. 错误错误
展开解析
答案:错误
链表删除操作
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 单向链表删除节点必须修改前驱节点的 next 指针,因此必须知道前一个节点的位置。
  2. 仅知道当前地址无法直接获取前驱。
易错点:认为只需释放内存即可,忽略了链表指针逻辑的维护。
判断题 6BFS算法实现

在宽度优先搜索中,通常使用队列来辅助实现。

  1. 正确正确
  2. 错误错误
展开解析
答案:正确
BFS算法实现
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 宽度优先搜索(BFS)利用队列先进先出的特性来保证按层访问节点。
易错点:混淆 BFS(用队列)与 DFS(用栈或递归)的实现工具。
判断题 7哈夫曼编码性质

哈夫曼编码的主要应用领域是有损数据压缩。

  1. 正确正确
  2. 错误错误
展开解析
答案:错误
哈夫曼编码性质
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 哈夫曼编码是一种无损数据压缩算法,压缩后的数据可以被完全、准确地恢复。
易错点:混淆无损压缩与有损压缩(如 JPEG 等)的应用场景。
判断题 8BST 查找复杂度分析

二叉搜索树的查找操作的时间复杂度是 𝑂 ( 𝑁 ) O(N)

  1. 正确正确
  2. 错误错误
展开解析
答案:错误
BST 查找复杂度分析
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 二叉搜索树的查找平均复杂度为 O(\log N),只有在最坏情况下(树退化为链表)才为 O(N)
  2. 断言描述不全面。
易错点:忽略平衡性对二叉树查找效率的影响。
判断题 9栈的基本操作

栈的基本操作包括入栈(push)和出栈(pop)。

  1. 正确正确
  2. 错误错误
展开解析
答案:正确
栈的基本操作
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 栈是受限线性表,其核心操作就是在栈顶进行入栈(Push)和出栈(Pop)。
易错点:无。
判断题 10哈夫曼编码的前缀性质

使用哈夫曼编码对一些字符进行编码,如果两个字符的频率差异最大,则它们的编码可能出现相同的前缀。

  1. 正确正确
  2. 错误错误
展开解析
答案:错误
哈夫曼编码的前缀性质
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 哈夫曼编码是前缀编码(Prefix Code),没有任何编码是另一个编码的前缀。
  2. 这是由字符仅存在于叶子节点这一性质决定的。
易错点:错误理解前缀编码的定义,认为频率差异大可能导致包含关系。
答案速查表

单选题

1A2D3A4D5B6B7C8C9D10B11A12A13C14C15A

判断题

1正确2正确3正确4错误5错误6正确7错误8错误9正确10错误