LeetCode 面试经典 150_二叉树层次遍历_二叉树的层序遍历(83_102_C++_中等)

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)原题链接

欢迎大家和我沟通交流(✿◠‿◠)

相关推荐
xlq223222 小时前
15.list(上)
数据结构·c++·list
王中阳Go2 小时前
面试被挂的第3次,面试官说:你懂的LLM框架,只够骗骗自己
面试·职场和发展
Elias不吃糖3 小时前
总结我的小项目里现在用到的Redis
c++·redis·学习
terminal0073 小时前
浅谈useRef的使用和渲染机制
前端·react.js·面试
AA陈超3 小时前
使用UnrealEngine引擎,实现鼠标点击移动
c++·笔记·学习·ue5·虚幻引擎
No0d1es4 小时前
电子学会青少年软件编程(C/C++)六级等级考试真题试卷(2025年9月)
c语言·c++·算法·青少年编程·图形化编程·六级
不会c嘎嘎4 小时前
每日一练 -- day1
c++·算法
yy_xzz5 小时前
VCPKG && Tesseract OCR
c++·图像处理·opencv
hansang_IR5 小时前
【记录】网络流最小割建模三题
c++·算法·网络流·最小割
玖笙&5 小时前
✨WPF编程进阶【7.3】集成动画(附源码)
c++·c#·wpf·visual studio