题目描述
接口函数以及二叉树节点结构如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
}
};
题目来源:LeetCode 107. 二叉树的层序遍历 II
核心定义
二叉树的层序遍历,又称广度优先遍历(BFS),是指从根节点开始,按'从上到下、从左到右'的顺序逐层访问树中所有节点。先遍历完第 1 层(根节点),再遍历第 2 层,以此类推,直到最后一层的所有节点都被访问。

实现思路
二叉树层序遍历的本质是'先进先出'的访问逻辑,队列是实现该逻辑的关键数据结构。
大概思路:将二叉树节点的地址存入队列,用一个变量记录每一层的节点个数,和一个数组存储每一层数据。利用计数器控制节点出队列的个数,保证每一层的节点都能够出尽。在节点出队列的同时将节点的 val 值插入数组并将该节点不为空的孩子节点继续带入队列。这样每循环一次得到一层的数据,直到遍历完整个二叉树。
解题步骤
- 创建二维数组
vv用于存储最终结果。 - 判断二叉树是否为空,即根结点
root是否为nullptr。若为空则返回空的二维数组;不为空,则将根结点入队列,同时记录节点个数为 1。 - 根据当前层节点数遍历已经入队列的节点。用当前层节点数作为 while 循环次数来遍历节点,利用队列的 front 接口获取队头节点,将队头节点的 val 值插入到数组 v,然后将该节点不为空的孩子节点带入队列,同时将队头节点出队列。
注意: a. 这里不能直接将节点直接出队列,防止节点被释放而找不到孩子节点。可以用临时变量记下该节点,然后 pop(删除队头节点)。 b. 每次出队头节点都要保证将其对应的不为空的左右孩子节点带入队列,保证在下一次遍历时,下一层的所有节点都在队列中,便于准确更新下一层的节点数。
- 遍历完一层的节点之后,将数组 v 中的数据插入到二维数组 vv,然后更新下一层节点的个数。
- 当队列中再没有节点时,证明二叉树的所有节点已经都遍历完了。因为题目要求从二叉树的叶子节点所在层开始向上遍历,所以先将二维数组 vv 进行逆置处理,再返回即可。
流程示意

代码实现
std;
{
:
vector<vector<>> (TreeNode* root) {
vector<vector<>> vv;
(root != ) {
_q.(root);
level_k_size = ;
}
(!_q.()) {
vector<> v;
(level_k_size--) {
TreeNode* node = _q.();
_q.();
v.(node->val);
(node->left) {
_q.(node->left);
}
(node->right) {
_q.(node->right);
}
}
vv.(v);
level_k_size = _q.();
}
(vv.(), vv.());
vv;
}
:
queue<TreeNode*> _q;
level_k_size = ;
};



