GESP 六级 · GESP 202606 C++ 六级 第 23 题

判断题 · 答案 B · 考点:队列(queue)

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

题目

以下代码可以正确地按层换行输出二叉树的节点值。

void printByLevel(TreeNode* root) {
    if (!root) return;
    queue<TreeNode*> q;
    q.push(root);
    while (!q.empty()) {
        for (int i = 0; i < q.size(); ++i) {
            TreeNode* cur = q.front();
            q.pop();
            cout << cur->val << " ";
            if (cur->left) q.push(cur->left);
            if (cur->right) q.push(cur->right);
        }
        cout << endl;
    }
}
答案:B

考点

队列(queue) 讲解 →队列(queue) 真题汇总 →

解题思维

排列组合问题:先判断是否考虑顺序(排列P vs 组合C),再确定是否允许重复。乘法原理分步,加法原理分类。

常见错误

区分排列(考虑顺序,$P(n,m)$)和组合(不考虑顺序,$C(n,m)$)。注意特殊元素优先处理、正难则反等计数技巧。

详细解析(节选)

【考点】队列|二叉树遍历|循环不变量

---

考纲定位

GESP六级C++「数据结构」模块,具体是「二叉树遍历」与「队列」考点。命题人把这道题塞进试卷,就是为了卡住那些只背「层序遍历要队列」的结论、却不懂队列操作细节的考生——知道该用队列,却写错循环条件,是六级最大的失分点。

解题思维

看到题先想:队列是什么?先进先出,每层循环完队列里正好是下一层节点。那内层循环跑几次?应该是「当前队列里有多少个元素」。但代码里写的是 for (int i = 0; i < q.size(); ++i),q.size() 在每次迭代里都会变小,因为你在循环里 pop() 了。

正确思路是:先把当前层的元素个数「快照」下来,用这个固定值控制循环。通法就是:任何层序遍历,先 int n = q.size(); 再 for (int i = 0; i < n; ++i)。这一招能迁移到所有「按固定批次处理队列」的题,比如 BFS 找最短路径、按圈处理链表等。

陷阱拆解

选项 A 看起来完美,就是「正确」这个绝对化表述坑了你——它没告诉你代码到底对不对。命题人利用的是「只背结论不验逻辑」的思维误区:记住了「层序遍历用队列」,就默认代码无误,不再细看循环条件。

最阴险的细节是:q.size() 在每次 pop() 后立刻变化,导致循环次数少于当前层实际节点数,后面的节点根本不会入队。如果你不理解队列的「当前大小」是动态的,只盯着「层序遍历」四个字,就会掉进这个陷阱。

反命题思维

站在命题人角度:如果我把 for (int i = 0; i < q.size(); ++i) 改成 for (int i = 0; i < n; ++i),答案就变成 A;如果我再在循环里 q.pop() 两次,答案又变回 B。

刷到类似题,先问自己:「命题人想考我什么?」答案永远藏在「循环条件是否固定」和「队列操作是否匹配」这两点里。

同考点真题

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