GESP6 · 2023年12月真题

客观题逐题精讲

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

一、考点地图

递归与动态规划的效率对比1 题
二叉树的序列与括号表示法1 题
二叉树递归函数的参数1 题
二叉树前序遍历1 题
二叉搜索树(BST)时间复杂度1 题
二叉搜索树(BST)性质定义1 题
哈夫曼编码的非唯一性1 题
霍夫曼编码位长度计算1 题
计算机网络通信基础1 题
静态成员变量访问1 题
链表排序时间复杂度分析1 题
面向对象成员函数概念1 题

二、单选题逐题讲

单选题 1C++类与函数定义

关于C++类和对象的说法,错误的是()。

  1. A在C++中,一切皆对象,即便是字面量如整数5等也是对象
  2. B在C++中,可以自定义新的类,并实例化为新的对象
  3. C在C++中,内置函数和自定义函数,都是类或者对象
  4. D在C++中,可以在自定义函数中嵌套定义新的函数
展开解析
答案:D
C++类与函数定义
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. C++标准不支持在函数内部嵌套定义另一个命名的函数。
  2. 选项A、B、C虽然在严谨术语上略有简化,但D项描述的“函数嵌套”在C++语法中是明确错误的。
易错点:混淆局部类(Local Class)的定义与嵌套函数定义的区别。
单选题 2内部类访问权限

有关下面C++代码的说法,错误的是()。

class Rectangle
{
private:
    class Point
    {
    public:
        double x;
        double y;
    };
    Point a, b, c, d;
    double length;
    double width;
public:
  1. AC++中类内部可以嵌套定义类
  2. B在类中定义的类被称为内部类,定义类的类被称为外部类
  3. C内部类可以随便访问,不需要通过外部类来访问
  4. D代码中 Point 被称为内部类,可以通过外部类 Rectangle 来访问,Rectangle::Point
展开解析
答案:C
内部类访问权限
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 内部类(嵌套类)受外部类的访问说明符(public/private/protected)限制。
  2. 如果 Point 定义在 private 下,则外部无法直接通过 Rectangle::Point 访问,必须遵循封装规则。
易错点:误认为内部类会自动获得全局访问权限,忽略了外部类的访问限制。
单选题 3静态成员变量访问

有关下面C++代码的说法,正确的是()。

using namespace std;
class newClass
{
public:
    static int objCounter;
};

int newClass::objCounter = 2;

int main()
{
    newClass classA;
    newClass classB;
    cout << newClass::objCounter << endl;
    cout << classB.objCounter << endl;
}
  1. A第14行代码错误,第15行正确
  2. B第15行代码错误,第14行代码正确
  3. C第14、15两行代码都正确
  4. D第6行代码可修改为 objCounter += 1
展开解析
答案:C
静态成员变量访问
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 静态成员变量为所有类对象共享。
  2. 在 C++ 中,既可以使用类名加作用域限定符(newClass::objCounter)访问,也可以通过具体的对象实例(classB.objCounter)访问,两者皆合法。
易错点:误以为静态成员只能通过类名访问,不知道也可以通过对象名访问。
单选题 4析构函数定义与规则

有关下面 C++ 代码的说法,错误的是()。

struct BiNode {
    char data;
    BiNode* lchid, *rchid;
};

class BiTree {
private:
    BiNode* Creat();
    void Release(BiNode* bt);
    BiNode* root;
public:
    BiTree() {
        root = Creat();
    }
    ~BiTree() {
        Release(root);
    }
};
  1. A上列C++代码适用于构造各种二叉树
  2. B代码 struct BiNode 用于构造二叉树的节点
  3. C代码 BiTree() {root=Creat();} 用于构造二叉树
  4. D析构函数不可以省略
展开解析
答案:D
析构函数定义与规则
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 虽然在该代码中需要析构函数来释放动态内存,但在 C++ 语法上,如果用户不自定义析构函数,编译器会自动生成默认析构函数,因此析构函数并不是“不可以省略”的语法要求。
易错点:混淆“逻辑上的内存泄露风险”与“语言语法上的硬性规定”。
单选题 5二叉树前序遍历

基于第4题的定义,有关下面C++代码的说法正确的是()。

void Order(BiNode* bt) {
    if (bt == nullptr)
        return;
    else {
        cout << bt->data;
        Order(bt->lchid);
        Order(bt->rchid);
    }
}
  1. A代码中 Order() 函数是中序遍历二叉树的方法
  2. B代码中 Order() 先访问根节点,然后对左子树进行前序遍历,再对右子树前序遍历
  3. C代码中 Order() 先访问中序遍历左子树,然后访问根节点,最后则是中序遍历右子树
  4. D代码中 Order() 先后序遍历左子树,然后后序遍历右子树,最后访问根节点
展开解析
答案:B
二叉树前序遍历
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 代码中首先执行 cout << bt->data 访问当前根节点,随后递归访问左子树和右子树。
  2. 这种“根 -> 左 -> 右”的访问顺序符合前序遍历的定义。
易错点:未能准确识别递归代码中访问语句(cout)所处的位置决定的遍历顺序。
单选题 6双向链表存储结构

有关下面C++代码的说法正确的是()。

typedef struct LinkList {
    int data;
    LinkList* next;
    LinkList* prev;
};

bool ListInit(LinkList* &L) {
    L = new LinkNode;
    if (!L) return false;
    L->next = NULL;
    L->prev = NULL;
    L->data = -1;
    return true;
}
  1. A上述代码构成单向链表
  2. B上述代码构成双向链表
  3. C上述代码构成循环链表
  4. D上述代码构成指针链表
展开解析
答案:B
双向链表存储结构
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 结构体 LinkList 中包含 next(指向后继节点)和 prev(指向前驱节点)两个指针,这构成了典型的双向链表结构。
易错点:忽略了 prev 指针的作用,或将其误认为其他类型的链表。
单选题 7霍夫曼编码位长度计算

对 hello world 使用霍夫曼编码(Huffman Coding),最少 bit(比特)为( )。

  1. A4
  2. B32
  3. C64
  4. D88
展开解析
答案:B
霍夫曼编码位长度计算
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 'hello world' 包含 11 个字符(含空格)。
  2. 统计频率:l(3), o(2), h(1), e(1), ' '(1), w(1), r(1), d(1)。
  3. 构建霍夫曼树并计算带权路径长度 WPL,结果为 32 bit。
易错点:统计字符频率时遗漏空格字符,或在构建霍夫曼树计算长度时出错。
单选题 8递归与动态规划的效率对比

下面的 fiboA() 和 fiboB() 两个函数分别实现斐波那契数列,该数列第1、第2项值为1,其余各项分别为前两项之和。下面有关说法错误的是()。

int fibroA(int n)
{
    if(n==0)
        return 1;
    if(n==1)
        return 1;
    else
    {
        return fibroA(n-1)+fiboA(n-2);
    }
}

int fibroB(int n)
{
    if((n==0)||(n==1))
        fiboB[n]=n;
    return n;
}

else
{
    if(fiboB[n] == 0)
        fiboB[n]=FiboB(n-1)+FiboB(n-2);
    return fibroB[n];
}
  1. AfiboA() 采用递归方式实现斐波那契数列
  2. BfiboB() 采用动态规划算法实现斐波那契数列
  3. C当N值较大时,fiboA() 存在大量重复计算
  4. D由于 fiboA() 代码较短,其执行效率较高
展开解析
答案:D
递归与动态规划的效率对比
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. fiboA() 使用普通递归,存在大量重叠子问题的重复计算,时间复杂度为指数级 O(2^n)
  2. fiboB() 采用记忆化存储,时间复杂度为 O(n),效率远高于 fiboA()。
  3. 代码长度不决定执行效率。
易错点:片面认为代码行数越少则执行效率越高,忽略了递归调用的开销。
单选题 9二叉树递归函数的参数

有关下面C++代码不正确的说法是()。

int Depth(BiTree T)
{
    if (T == NULL)
    {
        return 0;
    }
    else
    {
        int m = Depth(T->lchild);
        int n = Depth(T->rchild);
        if (m > n)
        {
            return m + 1;
        }
        else
        {
            return n + 1;
        }
    }
}
  1. A该代码可用于求解二叉树的深度
  2. B代码中函数 Depth() 的参数 T 表示根节点,非根节点不可以作为参数
  3. C代码中函数 Depth() 采用了递归方法
  4. D代码中函数 Depth() 可用于求解各种形式的二叉树深度,要求该二叉树节点至少有 left 和 right 属性
展开解析
答案:B
二叉树递归函数的参数
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 递归求解二叉树深度时,函数的参数可以是树中任何一个节点,用于计算以该节点为根的子树深度。
  2. 并不限定只能传递整棵树的根节点。
易错点:误以为递归算法的入口参数必须是全局唯一的根节点。
单选题 10树的存储结构

下面有关树的存储,错误的是().

  1. A完全二叉树可以用 list 存储
  2. B一般二叉树都可以用 list 存储,空子树位置可以用 None 表示
  3. C满二叉树可以用 list 存储
  4. D树数据结构,都可以用 list 存储
展开解析
答案:D
树的存储结构
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 完全二叉树和满二叉树可以通过数组下标建立父子关系,适合用线性表存储。
  2. 但对于一般的多叉树或无规律的树,直接用线性列表(不记录索引关系)无法有效表示其层级结构。
易错点:将特定类型二叉树的线性存储特性推广到所有通用的树结构。
单选题 11二叉树的序列与括号表示法

构造二叉树 [1,2,3,null,4]()。

  1. A1(2)(4)(3)
  2. B1(2(3)(4)
  3. C(1,2(3),(4))
  4. D(1,(2)(3),(4))
展开解析
答案:A
二叉树的序列与括号表示法
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 层序序列 [1,2,3,null,4] 对应:1为根,左子2,右子3,2的右子为4。
  2. 括号法 1(2)(4)(3) 是一种变体描述方式,对应 1 的左子树是 (2)(4),右子树是 (3)。
易错点:对层序序列转换为逻辑树形结构的过程理解不清晰。
单选题 12C++ bool 数据类型

下面有关布尔类型的函数的说法,正确的是()。

  1. Abool 类型函数只能返回0或者1两种值
  2. Bbool 类型函数可以返回任何整数值
  3. Cbool 类型函数必须有参数传递
  4. Dbool 类型函数没有返回值
展开解析
答案:A
C++ bool 数据类型
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. bool 类型在逻辑上仅代表“真”和“假”。
  2. 在 C++ 内部实现中,通常以 1 代表 true,0 代表 false。
  3. 虽然非零整数可转为真,但 bool 函数本身的返回值类型决定了其逻辑结果只有两种。
易错点:混淆 bool 类型的逻辑取值空间与整型数据的隐式转换。
单选题 13计算机网络通信基础

通讯卫星在通信网络系统中主要起到()的作用。

  1. A信息过滤
  2. B信号中继
  3. C避免攻击
  4. D数据加密
展开解析
答案:B
计算机网络通信基础
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 通讯卫星主要部署在地球同步轨道,充当无线电波的“空间中继站”,接收地面站信号并放大转发到另一地面站,实现远程通信的中继功能。
易错点:误选加密、过滤等安全管理功能,忽视了卫星在物理层面的信号转发本质。
单选题 14素数判定算法适用性

小杨想编写一个判断任意输入的整数 N 是否为素数的程序,下面哪个方法不合适?()

  1. A埃氏筛法
  2. B线性筛法
  3. C二分答案
  4. D枚举法
展开解析
答案:C
素数判定算法适用性
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 素数判定可使用试除枚举、埃氏筛或线性筛。
  2. 二分答案要求解空间具有单调性,而一个数是否为素数并不随数值增大呈现单调变化,因此二分法不适用。
易错点:盲目套用二分搜索模板,未识别出素数属性在数轴上不具备单调性。
单选题 15排序算法分类

内排序有不同的类别,下面哪种排序算法和冒泡排序是同一类?()

  1. A希尔排序
  2. B快速排序
  3. C堆排序
  4. D插入排序
展开解析
答案:B
排序算法分类
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. 冒泡排序和快速排序都属于“交换排序”。
  2. 其核心操作是通过元素间的两两比较和必要的位置交换来移动数据元素,从而达到有序状态。
易错点:混淆不同类别的排序算法(如插入类、选择类、交换类、归并类)。

三、判断题逐题讲

判断题 1面向对象成员函数概念

在面向对象中,方法在C++的class中表现为class内定义的函数。()

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

分步推导

  1. 在面向对象理论中,“方法(Method)”用于描述对象的行为。
  2. 在 C++ 语言中,这些行为通过在类(class)内部定义的成员函数来实现。
易错点:不理解抽象的“方法”概念与具体语言中“成员函数”的对应关系。
判断题 2默认构造函数规则

C++类的定义中,可以没有构造函数,会给出默认的构造函数()

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

分步推导

  1. 如果 C++ 类中没有显式定义任何构造函数,编译器会自动为该类生成一个默认的无参构造函数,以确保对象可以被实例化。
易错点:误以为必须手动书写构造函数,忽略了编译器的自动生成机制。
判断题 3C++ 运算符重载规则

如果某个 C++ 对象(object)支持下标运算符(方括号运算符),则该对象在所对应 class 中以成员函数的形式进行了重载。()

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

分步推导

  1. 在 C++ 标准中,下标运算符 [] 属于必须作为成员函数重载的运算符之一,不能重载为非成员函数或友元函数。
易错点:混淆哪些运算符可以重载为全局函数,哪些必须是成员函数。
判断题 4深度优先搜索(DFS)原理

深度优先搜索(DFS,Depth First Search的简写)属于图算法,其过程是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。()

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

分步推导

  1. DFS 采用回溯思想,优先向深层节点探索直至无法继续,再回退到上一个分叉点。
  2. 过程中通过标记位确保每个节点只被访问一次。
易错点:混淆 DFS 的“深入”策略与 BFS 的“逐层”搜索策略。
判断题 5哈夫曼编码的非唯一性

哈夫曼编码(Huffman Coding)具有唯一性,因此有确定的压缩率。()

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

分步推导

  1. 对于同一组频率,哈夫曼树的左右子树分配(0或1)以及同频率节点的处理是不唯一的,因此编码本身不唯一。
  2. 但其生成的总编码长度(压缩率)是确定的最优值。
易错点:将压缩效率的“确定性”误认为是具体编码序列的“唯一性”。
判断题 6内存释放与悬挂指针(Dangling Pointer)

在下面C++代码中,由于删除了变量 ptr,因此 ptr 所对应的数据也随之删除,故第8行代码被执行时,将报错。()

int *ptr = new int(10);
cout << *ptr << endl;
delete ptr;
cout << *ptr << endl;
  1. 正确正确
  2. 错误错误
展开解析
答案:错误
内存释放与悬挂指针(Dangling Pointer)
思考路径:先看这是概念判断、代码阅读还是计算题;再把题干限制拆成 2-4 个小步骤,最后对照选项排除常见误区。

分步推导

  1. delete ptr 释放了指针指向的堆内存,但 ptr 变量本身并未消失且仍存储着旧地址。
  2. 再次访问会导致未定义行为,不一定会立即“报错”。
易错点:误以为 delete 操作会连同指针变量本身一起销毁。
判断题 7二叉搜索树(BST)时间复杂度

二叉搜索树查找的平均时间复杂度为 𝑂 ( log ⁡ 𝑁 ) O(logN)。()

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

分步推导

  1. 在二叉搜索树中,查找操作类似于二分查找。
  2. 在树结构相对平衡的情况下(或随机分布的平均情况下),其查找的时间复杂度为 O(log N)
易错点:未区分最坏情况(退化成链表,O(N))与平均情况的时间复杂度。
判断题 8二叉搜索树(BST)性质定义

二叉搜索树可以是空树(没有任何节点)或者单节点树(只有一个节点),或者多节点。如果是多节点,则左节点的值小于父节点的值,右节点的值大于父节点的值,由此推理,右节点树的值都大于根节点的值,左节点树的值都小于根节点的值。()

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

分步推导

  1. 二叉搜索树的核心性质是:任一节点的左子树上所有节点的值均小于它,右子树上所有节点的值均大于它。
  2. 这是该数据结构支持高效查找的基础。
易错点:仅关注节点与其直接子女的关系,忽视了“整个子树”与根节点的数值关系。
判断题 9因数查找的优化算法

小杨想写一个程序来算出正整数N有多少个因数,经过思考他写出了一个重复没有超过N/2次的循环就能够算出来了。()

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

分步推导

  1. 求一个数 N 的因数时,除了 N 本身,所有因数必然分布在 [1, N/2] 区间内。
  2. 因此循环到 N/2 即可找全所有因数,甚至可以优化到 sqrt(N)。
易错点:误以为必须遍历到 N 才能找全所有因数,不了解数值分布的对称性。
判断题 10链表排序时间复杂度分析

同样的整数序列分别保存在单链表和双向链中,这两种链表上的简单冒泡排序的复杂度相同。()

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

分步推导

  1. 冒泡排序依赖于相邻元素的比较和交换。
  2. 在单链表和双向链表中,访问相邻节点及执行交换操作的时间代价均为 O(1),因此整体复杂度均为 O(N^2)
易错点:认为双向链表增加了指针会改变算法的渐进复杂度量级。
答案速查表

单选题

1D2C3C4D5B6B7B8D9B10D11A12A13B14C15B

判断题

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