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:层次遍历(广度优先搜索))):
//二叉树的层次遍历
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;
    }
};

代码实现(思路一的另一种代码呈现形式):
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;
    }
};
以思路一为例进行调试
#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)

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)原题链接
欢迎大家和我沟通交流(✿◠‿◠)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值