GESP 五级 · GESP 202509 C++ 五级 第 2 题

选择题 · 答案 C · 考点:链表

← 整套速查表 GESP 五级 全部真题

题目

函数 removeElements 删除单链表中所有结点值等于 val 的结点,并返回新的头结点。其中链表头结点为 head,则横线处填写( )。

// 结点结构体
struct Node {
    int val;
    Node* next;
    Node() : val(0), next(nullptr) {}
    Node(int x) : val(x), next(nullptr) {}
    Node(int x, Node* next) : val(x), next(next) {}
};

Node* removeElements(Node* head, int val) {
    Node dummy(0, head);      // 睡结点,统一处理头结点
    Node* cur = &dummy;
    while (cur->next != nullptr) {
        if (cur->next->val == val) {
            ________________ // 在此处填入代码
        } else {
            cur = cur->next;
        }
    }
    return dummy.next;
}

A.

Node* del = cur;
cur = del->next;
delete del;

B.

Node* del = cur->next;
cur->next = del;
delete del;

C.

Node* del = cur->next;
cur->next = del->next;
delete del;

D.

Node* del = cur->next;
delete del;
cur->next = del->next;
答案:C

考点

链表 讲解 →链表 真题汇总 →

解题思维

根据上下文和C++语法规则确定空缺处应填的内容,关注函数调用参数、表达式和返回值类型。

常见错误

填空时注意语法完整性:分号、括号匹配、函数参数类型和个数、返回值类型。

详细解析(节选)

【考点】链表遍历|哑结点技巧|指针操作顺序

1. 🎯 考纲定位 本题考查 GESP 五级“指针与内存管理”与“链表基本操作”的交叉点。命题人特意把“删除头结点”的场景用哑节点(dummy node)包装,卡住的是那些只背“头结点单独处理”结论、不懂“哑节点统一处理”通法的考生。这一行代码其实是在考“如何安全地跳过链表节点”——这是指针操作中最容易出错的细节。

2. 🧠 解题思维 看到哑节点 dummy 和 cur = &dummy,立刻明白这是为了“统一处理头结点”——不用单独判断 head 是否为空或是否要删。循环里 cur->next 就是当前要检查的结点,一旦值等于 val,就要“跳过”它:让 cur->next 指向 cur->next->next。删除结点时,必须先用临时指针保存被删结点(避免删除后取不到 next),再修改前驱指针,最后 delete。这一类“链表删除某个值”的题,通法永远是:哑节点 + 指针遍历 + 临时指针保存被删结点 + 修改前驱 + 释放。

3. 🪤 陷阱拆解 A 把 cur 指向哑节点删了(cur = del->next 后 del 是哑节点),直接破坏链表头;B 把 cur->next 赋值给自己(cur->next = del),等于没删;D 先 delete del 再访问 del->next,这是悬空指针必挂。最阴险的是 D:你一看“删除结点”就想到 delete,但链表里删除必须“先改指针再删”,否则释放了结点就取不到它的后继。如果你只背结论、不理解本质,就会掉进这个陷阱。

4. 🔄 反命题思维 命题人如果改成“删除所有值等于 val 的结点且 val 是链表最后一个结点的值”,那 cur->next 就是 nullptr,循环条件 cur->next != nullptr 会自动退出,不用额外处理。刷到类似题先问:哑节点是不是真的“哑”?如果直接 head 开始删,头结点会丢,所以必须用哑节点。

同考点真题

在 OI伴学 里做这道题
登录后可计时作答、查看完整六段式解析,并按你的错题自动生成同类练习。
去刷题先做一次 AI 学情诊断