LeetCode 面试经典 150_二叉树层次遍历_二叉树的层序遍历(83_102_C++_中等)
题目描述:
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
输入输出样例:
示例 1:

输入 :root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:
输入 :root = [1]
输出:[[1]]
示例 3:
输入 :root = []
输出:[]
提示:
树中节点数目在范围 [0, 2000] 内
-1000 <= Node.val <= 1000
题解:
解题思路:
思路一(BFS:层次遍历(广度优先搜索)):
1、层次遍历就是一层一层结点的遍历,我们可以采用先进先出的队列来实现。
2、具体思路如下:
① 将根结点存入队列
② 一个结点出队列之后将该结点的左右孩子依次入队(左右孩子不为空才能入队)
③重复上述②过程直至队列为空
2、复杂度分析:
① 时间复杂度:O(n),遍历整个二叉树一遍。
② 空间复杂度:O(width),width代表二叉树的宽度(也可记作O(n)因队列中元素不可能超过O(n))。
代码实现
代码实现(思路一(BFS:层次遍历(广度优先搜索))):
cpp
//二叉树的层次遍历
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> ans;
if (root==nullptr) return ans;
//创建队列,先将根节点入队
queue<TreeNode *> q;
q.push(root);
//当队列为空的时候遍历完整个树
while (!q.empty())
{
//每层结点的个数
int size=q.size();
//在ans中创建一个vector用于存储本层结点
ans.push_back(vector<int>());
//遍历本层结点
for (int i = 0; i < size; ++i)
{
//取队头元素,出队
TreeNode *node=q.front();
q.pop();
//将当前节点的值 node->val 添加到 ans 的最后一个子 vector<int> 中
ans.back().push_back(node->val);
//将结点的左右孩子入队(空则不入队)
if (node->left!=nullptr) q.push(node->left);
if(node->right!=nullptr) q.push(node->right);
}
}
return ans;
}
};
代码实现(思路一的另一种代码呈现形式):
cpp
class Solution {
public:
// 层次遍历二叉树,返回每一层的节点值组成的向量
vector<vector<int>> levelOrder(TreeNode* root) {
// 用于存储每一层节点的结果
vector<vector<int>> ans;
// 如果根节点为空,直接返回空的结果
if (root == nullptr) {
return ans;
}
// 使用队列进行层次遍历
queue<TreeNode *> Q;
Q.push(root); // 将根节点入队
// 开始层次遍历,直到队列为空
while (!Q.empty()) {
int size = Q.size(); // 当前层的节点数
vector<int> levelNodes; // 当前层的节点值
// 遍历当前层的所有节点
while (size) {
// 获取队首节点
TreeNode *curNode = Q.front();
levelNodes.push_back(curNode->val); // 将当前节点值加入当前层的结果
// 弹出队首节点
Q.pop();
// 如果左子节点存在,将其加入队列
if (curNode->left != nullptr) Q.push(curNode->left);
// 如果右子节点存在,将其加入队列
if (curNode->right != nullptr) Q.push(curNode->right);
// 当前层节点数减1
size--;
}
// 将当前层的节点值向量加入到最终结果中
ans.push_back(levelNodes);
}
// 返回存储每层节点值的结果
return ans;
}
};
以思路一为例进行调试
cpp
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
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 Soluton
{
public:
//二叉树的层次遍历
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> ans;
if (root==nullptr) return ans;
//创建队列,先将根节点入队
queue<TreeNode *> q;
q.push(root);
//当队列为空的时候遍历完整个树
while (!q.empty())
{
//每层结点的个数
int size=q.size();
//在ans中创建一个vector用于存储本层结点
ans.push_back(vector<int>());
//遍历本层结点
for (int i = 0; i < size; ++i)
{
//取队头元素,出队
TreeNode *node=q.front();
q.pop();
//将当前节点的值 node->val 添加到 ans 的最后一个子 vector<int> 中
ans.back().push_back(node->val);
//将结点的左右孩子入队
if (node->left!=nullptr) q.push(node->left);
if(node->right!=nullptr) q.push(node->right);
}
}
return ans;
}
//通过数组创建二叉树(数组元素为-1代表nullptr)
TreeNode *creatTree(vector<int> nums){
if(nums.empty()) return nullptr;
TreeNode *root=new TreeNode(nums[0]);
queue<TreeNode *> q;
q.push(root);
int i=1;
while (i<nums.size())
{
TreeNode *node=q.front();
q.pop();
if(i<nums.size()&&nums[i]!=-1){
node->left=new TreeNode(nums[i]);
q.push(node->left);
}
++i;
if(i<nums.size()&&nums[i]!=-1){
node->right=new TreeNode(nums[i]);
q.push(node->right);
}
++i;
}
return root;
}
//中序遍历输出二叉树(用于调试二叉树创建是否正确)
void inorder(TreeNode *root){
if(root==nullptr) return ;
inorder(root->left);
cout<<root->val<<" ";
inorder(root->right);
}
};
int main(){
vector<int> nums={1,2,3,4,5};
Soluton s;
//创建二叉树
TreeNode *root=s.creatTree(nums);
//调试二叉树是否创建正确
//s.inorder(root);
vector<vector<int>> ans=s.levelOrder(root);
//输出二叉树的层序遍历
for (const auto &row: ans)
{
cout<<"[";
for (const auto &i :row)
{
cout<<i<<" ";
}
cout<<"]";
}
return 0;
}
部分代码解读
ans.push_back(vector())和ans.back().push_back(node->val)
cpp
vector<vector<int>> ans;
ans.push_back(vector<int>());
ans.back().push_back(node->val);
1、ans.push_back(vector())的作用是在 ans 中增加一个空的 vector
2、ans.back().push_back(node->val);的作用将 node->val 添加到 ans 中最后一个 vector 里。
当然你也可以创建一个新的vector来存每层的数据,再将每层的数据存入ans中
LeetCode 面试经典 150_二叉树层次遍历_二叉树的层序遍历(83_102)原题链接
欢迎大家和我沟通交流(✿◠‿◠)