队列先进先出的性质, 符合 广度优先遍历时, 一层一层的遍历逻辑;
lc102
102.二叉树的层序遍历
107.二叉树的层次遍历II
199.二叉树的右视图
637.二叉树的层平均值
429.N叉树的层序遍历
515.在每个树行中找最大值
116.填充每个节点的下一个右侧节点指针
117.填充每个节点的下一个右侧节点指针II
104.二叉树的最大深度
111.二叉树的最小深度
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
1. 层序遍历迭代实现:
1.1 关键思想
-
层序遍历使用队列方式;
-
建立两个向量容器;
一个二维向量容器; 一个一维向量容器;
- 建立嵌套循环,
外层是条件循环, 当队列不为空时, 开始循环;
内存是循环遍历当前的队列大小,
并将此时队列的第一个节点的引用作为 当前节点;
将当前节点中的数值存入到 一维向量中;
分别将 当前节点的左子树入队;
当前节点的右子树入队;
1.2 步骤与 code
新建节点型 队列, 使用容器适配器queue;
如果根节点不为空, 将根节点入队;
新建二维向量容器 result, 用于层序的存放节点中元素;
条件循环, 当队列不为空:记录当前 队列的大小为 len1;
新建一个 一维向量容器 res;
循环遍历, 当前队列;
当前节点 等于 取出队列的第一个节点的引用;
删除队列的第一个节点;
一维向量容器中, 添加当前节点中的数值;
当前节点的左子树不为空, 左子树入队;
当前节点的右子树不为空, 右子树入队;
循环遍历当前队列的大小结束, 将一维容器存入到二维容器中;
条件循环结束, 当队列为空时; 返回二维向量容器;
#include "queue"
#include "vector"
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
vector<vector<int>> levelorder(TreeNode* root){
vector<vector<int>> result;
queue<TreeNode*> que;
if(root != nullptr) que.push(root);
while (!que.empty()){
int cur_size = que.size();
vector<int> res;
for(int i = 0; i < cur_size; i++){// 遍历当前队列中的节点
TreeNode* cur_node = que.front(); // 队列中的第一个节点的引用;
que.pop();
res.push_back(cur_node->val);
// 层序遍历时, 由于队列 先进先出, 满足 正常顺序;
if(cur_node->left) que.push(cur_node->left);
if(cur_node->right) que.push(cur_node->right);
}
result.push_back(res);
}
return result;
}
};
2. 层序遍历的其他题解:
2.1 code
#include "queue"
#include "vector"
#include "algorithm"
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution102{
vector<vector<int>> leverOrder(TreeNode* root){
vector<vector<int>> result;
queue<TreeNode*> que;
if(root != nullptr) que.push(root);
while (!que.empty()){
int cur_size = que.size();
vector<int> res;
for(int i = 0; i < cur_size; i++){
TreeNode* cur_node = que.front();
que.pop();
res.push_back(cur_node->val);
if(cur_node->left) que.push(cur_node->left);
if(cur_node->right) que.push(cur_node->right);
}
// 当前队列遍历结束后,代表当前层遍历结束, 将一维向量容器存入到二维向量容器中;
result.push_back(res);
}
return result;
}
};
class Solution107{
public:
vector<vector<int>> levelorder(TreeNode* root){
vector<vector<int>> result;
queue<TreeNode*> que;
if(root != nullptr) que.push(root);
while (!que.empty()){
int cur_size = que.size();
vector<int> res;
for(int i = 0; i < cur_size; i++){// 遍历当前队列中的节点
TreeNode* cur_node = que.front(); // 队列中的第一个节点的引用;
que.pop();
res.push_back(cur_node->val);
// 层序遍历时, 由于队列 先进先出, 满足 正常顺序;
if(cur_node->left) que.push(cur_node->left);
if(cur_node->right) que.push(cur_node->right);
}
result.push_back(res);
}
reverse(result.begin(), result.end());
return result;
}
};
class Solution199{
public:
vector<vector<int>> levelorder(TreeNode* root){
vector<vector<int>> result;
queue<TreeNode*> que;
if(root != nullptr) que.push(root);
while (!que.empty()){
int cur_size = que.size();
vector<int> res;
for(int i = 0; i < cur_size; i++){// 遍历当前队列中的节点
TreeNode* cur_node = que.front(); // 队列中的第一个节点的引用;
que.pop();
res.push_back(cur_node->val);
// 层序遍历时, 由于队列 先进先出, 满足 正常顺序;
if(cur_node->left) que.push(cur_node->left);
if(cur_node->right) que.push(cur_node->right);
}
result.push_back(res); // 此时 result 保存的是正常层序遍历的结果;
}
vector<int> right_side; // 用于存放左边的元素;
for( int i = 0; i < result.size(); i++){
right_side.push_back(result[i].back());
}
return result;
}
};
class Solution637{
vector<double> leverAverage(TreeNode* root){
vector<vector<int>> result;
queue<TreeNode*> que;
if(root != nullptr) que.push(root);
while (!que.empty()){
int cur_size = que.size();
vector<int> res;
for(int i = 0; i < cur_size; i++){
TreeNode* cur_node = que.front();
que.pop();
res.push_back(cur_node->val);
if(cur_node->left) que.push(cur_node->left);
if(cur_node->right) que.push(cur_node->right);
}
// 当前队列遍历结束后,代表当前层遍历结束, 将一维向量容器存入到二维向量容器中;
result.push_back(res);
}
vector<double> average; // 用于存放每层数的平均值;
for(int i = 0 ; i < result.size(); i++){
double cur_sum = 0; // 注意由于, 是除法 保留double 精度, 所以这里使用 double 类型表示当前层的和;
for(int j = 0 ; j< result[i].size(); j++){
cur_sum += result[i][j];
}
average.push_back( cur_sum / result[i].size());
}
return average;
}
};