1.问题描述
本题出自,leetcode102二叉树的层序遍历,给你二叉树的根节点 root
,返回其节点值的层序遍历。 (即逐层地,从左到右访问所有节点)。
2.解决思路
注意遍历的顺序,是把每一层的结点当成一个集合,最后把结果输出,也就是说在每层的最后一个(也就是每层中最右边的结点),我们就要把这层的结果push到最终的结果中并且进入下一层的操作了,需要对最后一个结点进行判断。我们应该思考,如何获取每层的最后一个元素(也就是每层中最靠右的结点)?首先需要在层序遍历的基础上,一个队列,存储一个pair对组,对组:pair<TreeNode *,int>,遍历每层把层数存进去,获取当前的结点的层数,判断队列是否还有元素,如果没有,就说明是当前层最后一个元素,如果有,就判断队头的层数是不是==当前节点的层数,不等于说明当前节点就是当前层的最后一个结点。
方法一:
所以我们可以,在外面定义一个res结果容器,还需要一个每一层的容器tmp用于存放每层的所有结点。获取这一层的一个元素,push进入tmp,判断是否有左子树和右子树,如果有就把对应的左右子结点push进入队列中。最后判断,当前节点是不是最后一个,如果是最后一个就把这层结果push进入res,并且清空这个容器。
方法二:
我们改进了遍历的思路,不再用队列存储一个结点和层数的对组,只需要存储结点就行。还是层序遍历,每一次循坏就直接把一层的结果push进入临时的容器中。定义size=q.size();由于我们每次循环都是处理一个层的元素,所以size就是每一层的元素个数。通过size遍历这一层元素,获取这一层的第一个元素,把他push进入临时容器中,并且pop,判断左右节点是否存在,然后进入这层的下一个结点。最后由于size的限制,不会把下一层的结点算进来。
3.代码实现
方法一:
vector<vector<int>> levelOrder(TreeNode* root) {
queue< pair<TreeNode*,int> > q;//用于存放队列树和层数
vector<vector<int>> res;
vector<int> vec;//每一层的集合
q.push(make_pair(root,0));
while(!q.empty())
{
TreeNode *node=q.front().first;//获取结点
int layer=q.front().second;//获取层数
q.pop();
vec.push_back(node->val);
if(node->left)//左子树存在
{
pair<TreeNode*,int> tmp(node->left,layer+1);
q.push(tmp);
}
if(node->right)//右子树存在
{
pair<TreeNode*,int> tmp(node->right,layer+1);
q.push(tmp);
}
if(q.empty() || layer<q.front().second)
{
res.push_back(vec);
vec.clear();
}
}
方法二:
vector<vector<int>> levelOrder(TreeNode* root) {
auto res= vector<vector<int> >();
queue<TreeNode *> q;
q.push(root);
if(root==nullptr) return res;
while(!q.empty())
{
int size=q.size();//
vector<int> tmp;
for(int i=0;i<size;++i)
{
TreeNode *node=q.front();
tmp.push_back(node->val);
q.pop();
if(node->left)
{
q.push(node->left);
}
if(node->right)
{
q.push(node->right);
}
}
res.push_back(tmp);
}
return res;
}
4.总结
二叉树的层序遍历主要就是队列的运用,还有几道题也是对本题的扩展,做了这几道题对于二叉树的层序遍历相关的题应该就没什么问题了。