一、题目描述:
给你二叉树的根节点
root
,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
二、输入输出实例:
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]]示例 2:
输入:root = [1] 输出:[[1]]示例 3:
输入:root = [] 输出:[]
三、思路讲解:
- 创建一个队列,用来存储树节点的指针。这个队列会最多存储两层的树节点,所以我们需要一个变量来得知队列的前几个节点是上一层,从哪个节点开始是下一层。
- 首先检查根节点是否为空。如果根节点为空,则没有节点需要遍历,直接返回空的结果向量。
- 如果根节点不为空,将根节点加入队列,因为根节点的那一层必定只有一个节点,所以将sz初始化为1。
- 使用一个
while
循环,只要队列不为空,就持续处理。- 在每一层的开始,初始化一个空向量
v
来存储该层的节点值。- 使用
sz
来控制内层while循环,sz为0表示当前层的所有节点都被处理。- 内层循环的作用是:从队列中取出一个节点,获取它的值并存储在当前层的结果向量
v
中。检查该节点的左子节点和右子节点,如果存在,则将它们加入队列,为下一层做准备。- 当前层的节点处理完毕后,将当前层的结果向量
v
加入最终结果向量vv
。- 更新
sz
为队列中元素的数量,即下一层的节点数。- 当队列为空时,所有层的节点都已处理完毕,返回结果向量
vv
。
四、C++代码:
- 包含注释的版本:
class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { queue<TreeNode*> q;//创建一个队列,存储每一个树节点的指针 int sz=0;//定义一个变量,用于统计当前层的节点数量 if(root)//如果数存在 { sz=1;//第一层只有一个节点,我们将sz设置为1 q.push(root);//将根节点的指针添加到队列 } vector<vector<int>> vv;//创建一个存放vector<int>类型的vector while(!q.empty())//如果队列不为空,说明队列中仍有树节点需要处理 { vector<int> v;//创建一个临时的vector存放当前层的每个节点的值 while(sz--)//sz不为0,说明当前层仍然有节点需要处理 { TreeNode* front=q.front();//设置一个树节点指针方便操作 q.pop();//出栈队列第一个元素 v.push_back(front->val);//将出栈的元素内部的值添加到vector中 if(front->left)//处理左子树节点 q.push(front->left);//如果节点不为空,就将节点的指针添加到队列 if(front->right) q.push(front->right); } sz=q.size();//队列当前的大小,就是下一层节点数量 vv.push_back(v);//将存放当前层元素的vector添加到总vector中 } return vv;//返回总vector } };
- 去注释版本 :
class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { queue<TreeNode*> q; size_t sz=0; if(root) { sz=1; q.push(root); } vector<vector<int>> vv; while(!q.empty()) { vector<int> v; while(sz--) { TreeNode* front=q.front(); q.pop(); v.push_back(front->val); if(front->left) q.push(front->left); if(front->right) q.push(front->right); } sz=q.size(); vv.push_back(v); } return vv; } };