从上到下打印二叉树系列(BFS模板)
从上到下打印二叉树 Ⅰ
题目描述
题目链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/
思路分析
- 我们从根节点开始按宽度优先的顺序遍历整棵树,每次先扩展左儿子,再扩展右儿子
- 先扩展根节点
- 再依次扩展根节点的左右儿子,也就是从左到右扩展第二层节点
- 再依次从左到右扩展第三层节点
- 依次类推
- 复杂度O(n)
代码实现
class Solution {
public:
vector<int> levelOrder(TreeNode* root)
{
//简单的bfs层序遍历
//把每个还未搜索的点依次放入队列,然后再弹出队列的头部元素作为当前遍历点
vector<int>res;
if(!root) return res;
queue<TreeNode*>q;
q.push(root);
while(q.size())
{
auto t=q.front();//此时等于获取了root
q.pop();
res.push_back(t->val);
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
return res;
}
};
从上到下打印二叉树 Ⅱ
题目描述
题目链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/
思路分析
- 这道题比上一题多了一个按行输出,所以我们BFS的思路不变
- 将根节点插入队列中
- 创建一个新队列,用来按顺序保存下一层的所有子节点
- 对于当前队列中的所有节点,按顺序依次将儿子加入新队列,并将当前节点的值记录在答案中
- 重复以上步骤,直到队列为空为止
- 我们用nullptr来标记每次的结束
- 复杂度O(n)
代码实现
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root)
{
vector<vector<int>>res;
if(!root) return res;
queue<TreeNode*>q;
q.push(root);
q.push(nullptr);
vector<int>level;//遍历树的层级
while(q.size())
{
auto t=q.front();
q.pop();
//如果说遍历完一整行了
if(!t)
{
//如果说level空了 说明遍历完所有结果了 eg:下一层没有节点了
if(level.empty()) break;
//否则就把level放到答案里面去并把level清空
res.push_back(level);
level.clear();
q.push(nullptr);
continue;
}
//否则就要扩展
//先把当前的点加到level里面去
level.push_back(t->val);
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
return res;
}
};
从上到下打印二叉树Ⅲ
题目描述
题目链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/
思路分析
- 这道题在上一题的基础又加了一个Z字型输出
- 所以我们在上一题的基础上加一个
bool sign
标记,bool sign =false表示:true的话就是从右到左输出,false的话就是从左到右输出
- 还是一个BFS搜索的思路+维护一个队列
代码实现
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root)
{
vector<vector<int>>res;
if(!root) return res;
queue<TreeNode*>q;
q.push(root);
q.push(nullptr);
vector<int>level;//遍历树的层级
bool sign=false; //true的话就是从右到左 false的话就是从左到右
while(q.size())
{
auto t=q.front();
q.pop();
//如果说遍历完一整行了
if(!t)
{
//如果说level空了 说明遍历完所有结果了 eg:下一层没有节点了
if(level.empty()) break;
//if(sign) 反转数组
if(sign) reverse(level.begin(),level.end());
//否则就把level放到答案里面去并把level清空
res.push_back(level);
level.clear();
q.push(nullptr);
sign=!sign;
continue;
}
//否则就要扩展
//先把当前的点加到level里面去
level.push_back(t->val);
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
return res;
}
};