算法练习-二叉树的层序遍历(思路+流程图+代码)

news2025/1/23 10:21:32

难度参考

        难度:中等

        分类:二叉树

        难度与分类由我所参与的培训课程提供,但需要注意的是,难度与分类仅供参考。且所在课程未提供测试平台,故实现代码主要为自行测试的那种,以下内容均为个人笔记,旨在督促自己认真学习。

题目

        给你二叉树的根节点root,返回其节点值的层序遍历。(即逐层地,从左到右访问所有节点)。
        示例1:
        输入:root=[3,9,20,null,null,15,7]
        输出:[3],[9,20],[15,7]
        提示:
        树中节点数目在范围[0,20]内
        -100<=Node.Val<=1000

思路

        对于这个问题,我们可以使用广度优先搜索(BFS)算法来进行二叉树的层序遍历。BFS 通常使用队列来实现,通过不断出队和入队的方式,将每一层的节点依次遍历。

  1. 首先,我们需要定义一个队列(queue)来存储待遍历的节点。初始时,将根节点(root)入队。
  2. 然后,进入循环,直到队列为空。在每一次循环中,分别执行以下步骤:
    • 从队列中取出当前节点,并将当前节点的值存入结果数组中(该层的结果数组)。
    • 如果当前节点的左子节点不为空,将左子节点入队。
    • 如果当前节点的右子节点不为空,将右子节点入队。
  3. 循环结束后,我们就能得到一个每层节点值的层序遍历结果数组。

        最后,根据题目的要求,返回层序遍历的结果数组。

示例

        假设我们有以下的二叉树:

     3
    / \
   9  20
     /  \
    15   7

        我们可以按照层序遍历的顺序逐层访问节点。根据题目要求,层序遍历的结果数组应该是 [3], [9, 20], [15, 7]

  1. 首先,将根节点 3 入队。
         3                     --------------------
        / \                      3
       9  20                   --------------------        
         /  \
        15   7                 result = {}
    
  2. 开始循环,第一层级只有根节点 3,所以当前队列中只有根节点 3。将根节点 3 出队,并将其值 3 放入当前层级结果数组中。然后,检查节点 3 的左右子节点,发现都不为空,将根节点的左子节点 9 入队,右子节点 20 入队。
         3                     --------------------
        / \                      9, 20
       9  20                   --------------------        
         /  \
        15   7                 result = {3}
    
  3. 进入下一层级循环。此时,队列中有两个节点,分别是节点 9 和节点 20。将节点 9 出队,并将其值 9 放入当前层级结果数组中。然后,检查节点 9 的左右子节点,发现都为空,所以不需要入队。接着,将节点 20 出队,并将其值 20 放入当前层级结果数组中。然后,将节点 20 的左子节点 15 入队,右子节点 7 入队。
         3                     --------------------
        / \                      15, 7
       9  20                   --------------------        
         /  \
        15   7                 result = {3, 9, 20}
    
  4. 再次进入下一层级循环。此时,队列中有两个节点,分别是节点 15 和节点 7。将节点 15 出队,并将其值 15 放入当前层级结果数组中。然后,检查节点 15 的左右子节点,发现都为空,所以不需要入队。接着,将节点 7 出队,并将其值 7 放入当前层级结果数组中。然后,检查节点 7 的左右子节点,发现都为空,所以不需要入队。
         3                     --------------------
        / \                      
       9  20                   --------------------        
         /  \
        15   7                 result = {3, 9, 20, 15, 7}
    
  5. 循环结束,得到层序遍历的结果数组 [3], [9, 20], [15, 7]

梳理

        对于二叉树的层序遍历,使用队列是因为队列的先进先出(FIFO)特性能够确保每一层的节点按照从左到右的顺序被访问

        具体来说,层序遍历的思路是从根节点开始,依次将节点的左子节点和右子节点加入到队列中,然后从队列中取出节点进行访问。这样做可以保证每一层的节点按照从左到右的顺序进行访问,因为队列中先入队的节点会先出队。

        通过使用队列,保证了层序遍历的节点访问顺序正确,能够按照层级逐步扩展,并且能够将每一层的节点按照顺序存储到结果数组中。

        具体流程中,我们通过循环不断从队列中取出节点,并将其值存入结果数组中。然后,检查当前节点的左右子节点,如果存在则将其加入到队列中,以便后续的访问。

        总结来说,队列在层序遍历中起到了承载节点的作用,能够确保每一层的节点按照顺序被访问。通过队列的先进先出特性,我们能够按照层级逐步扩展,从而得到二叉树的层序遍历结果。

代码

#include <iostream> // 包含输入输出流库
#include <queue> // 包含队列库
#include <vector> // 包含向量库

using namespace std; // 使用标准命名空间

// 定义二叉树的节点
struct TreeNode {
    int val; // 节点值
    TreeNode* left; // 左子节点指针
    TreeNode* right; // 右子节点指针
    
    // 构造函数
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

// 层序遍历函数
vector<vector<int>> levelOrder(TreeNode* root) {
    vector<vector<int>> result; // 存放最终层序遍历结果的向量
    
    // 如果根节点为空,直接返回空结果
    if (root == nullptr) {
        return result;
    }
    
    // 创建队列,并将根节点入队
    queue<TreeNode*> q;
    q.push(root);
    
    // 循环遍历队列,直到队列为空
    while (!q.empty()) {
        // 获取当前层的节点数量
        int size = q.size();
        vector<int> levelNodes; // 存放当前层节点值的向量
        
        // 遍历当前层的节点
        for (int i = 0; i < size; i++) {
            // 弹出队列首节点,并将其值存入结果数组中
            TreeNode* node = q.front();
            q.pop();
            levelNodes.push_back(node->val);
            
            // 将当前节点的左子节点和右子节点入队
            if (node->left) {
                q.push(node->left);
            }
            
            if (node->right) {
                q.push(node->right);
            }
        }
        
        // 将当前层的节点值数组存入结果数组中
        result.push_back(levelNodes);
    }
    
    // 返回结果数组
    return result;
}

int main() {
    // 创建示例树 [3, 9, 20, null, null, 15, 7]
    TreeNode* root = new TreeNode(3);
    root->left = new TreeNode(9);
    root->right = new TreeNode(20);
    root->right->left = new TreeNode(15);
    root->right->right = new TreeNode(7);

    // 执行层序遍历
    vector<vector<int>> result = levelOrder(root);

    // 输出结果
    for (const auto& level : result) { // 遍历每一层
        cout << "["; // 给输出结果添加左括号
        for (const auto& val : level) { // 遍历当前层的节点值
            cout << val << ","; // 输出节点值和逗号
        }
        cout << "]"; // 给输出结果添加右括号
    }
    
    return 0;
}

        时间复杂度:O(n)
        空间复杂度:O(n)

  1. pop 是队列的操作,用于移除队列中的队头元素(第一个元素)。
  2. push 是队列的操作,用于将元素添加到队尾。
  3. push_back 是向量的操作,用于将元素添加到向量的末尾。

        在代码中,首先创建一个空的队列 q,然后使用 q.push(root) 将根节点 root 添加到队列中。接下来,通过循环遍历队列,每次从队列中取出一个节点,并将其值添加到 levelNodes 向量中。
同时,如果节点有左子节点或右子节点,通过 q.push 将它们添加到队列的尾部,以便在后续循环中处理它们。
        最后,将 levelNodes 添加到 result 向量中,表示当前层的节点值。
整个过程将重复直到队列为空。最后返回 result 向量,即为二叉树的层序遍历结果。

        在主函数中,示例了如何使用 levelOrder 函数来执行对创建的二叉树进行层序遍历,并将结果输出到屏幕上。

打卡

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1424913.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EasyExcel根据对应的实体类模板完成多个sheet的写入与读取

1.展示模板一的实体类 import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.alibaba.excel.annotation.write.style.ContentRowHeight; import com.alibaba.excel.annotation.write.style.HeadRowH…

软件价值3-A*算法寻路

A*算法&#xff08;A-star算法&#xff09;是一种启发式搜索算法&#xff0c;主要用于在图或网络中找到从起始节点到目标节点的最佳路径。它结合了Dijkstra算法的广度优先搜索和贪婪最优优先搜索的特点&#xff0c;通过估算从起始节点到目标节点的代价来指导搜索方向。 A*算法…

CentOS 8最小安装

简介 CentOS 8的IOS如果下载DVD版本至少有10G 这里我们直接选择最小安装&#xff0c;因此选择最小系统boot版本 CentOS-8.5.2111-x86_64-boot.iso 下载地址 https://mirrors.aliyun.com/centos/8.5.2111/isos/x86_64/ 直接选择CentOS-8.5.2111-x86_64-boot.iso 大小只有789.0…

MIT6.5830 实验0

前置 本次实验使用 Golang 语言实现&#xff0c;在之前的年份中&#xff0c;都是像 cs186 那样使用 Java 实现。原因&#xff1a; Golang 语言作为现代化语言&#xff0c;简单易上手但功能强大。 使参加实验的同学有同一起跑线&#xff0c;而不是像Java那样&#xff0c;有些同…

鸿蒙HarmonyOS——AVSession开发指导

AVSession开发指导 说明&#xff1a; AVSession的所有接口均为系统接口&#xff0c;其功能仅提供给系统应用使用。 会话接入端开发指导 基本概念 会话元数据AVMetadata: 媒体数据相关属性&#xff0c;包含标识当前媒体的ID(assetId)&#xff0c;上一首媒体的ID(previousAsset…

链式二叉树(1)

目录 二叉树的概念&结构 二叉树的遍历概念 手写二叉树测试 二叉树遍历实现代码 递归图解 前序遍历递归图解 中序序遍历递归图解 后续遍历递归图解 二叉树的概念&结构 二叉树是&#xff1a; 空树非空&#xff1a;根节点&#xff0c;根节点的左子树、根节点的右子…

基于MongoDB实现聊天记录的存储

一、mongodb简介 1.1 mongodb简介 MongoDB是一个基于分布式文件存储的数据库&#xff0c;使用C语言编写。它旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB介于关系数据库和非关系数据库之间&#xff0c;是非关系数据库当中功能最丰富、最像关系数据库的。 Mong…

【TCP】三次握手(建立连接)

前言 在网络通信的世界里&#xff0c;可靠传输协议&#xff08;TCP&#xff09;扮演着重要的角色&#xff0c;它保证了数据包能够按顺序、完整地从发送端传送到接收端。TCP协议中有一个至关重要的机制——三次握手。这一过程确保了两个TCP设备在开始数据传输之前建立起一个稳定…

计算机毕业设计 | SpringBoot 房屋租赁网 房屋租赁平台(附源码)

1&#xff0c;绪论 1.1 背景调研 在房地产行业持续火热的当今环境下&#xff0c;房地产行业和互联网行业协同发展&#xff0c;互相促进融合已经成为一种趋势和潮流。本项目实现了在线房产平台的功能&#xff0c;多种技术的灵活运用使得项目具备很好的用户体验感。 这个项目的…

【Linux】环境基础开发工具的使用(一)

前言&#xff1a;在此之前我们学习了一些Linux的权限&#xff0c;今天我们进一步学习Linux下开发工具的使用。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:Linux的深度刨析 &#x1f448; &#x1f4af;代码仓库:卫卫周大胖的学习日记…

长时间佩戴骨传导耳机会损害听力吗?骨传导耳机有什么优点?

如果是正常的使用&#xff0c;是不会对损伤听力的&#xff0c;如果错误的使用&#xff0c;比如说高音量使用&#xff0c;长时间也会出现一定的危害&#xff0c;而且骨传导耳机相比于传统耳机&#xff0c;其优点也要多一些&#xff0c;下面一起看下骨传导耳机都有哪些优点吧。 佩…

dockerpipwork相关测试过程

pipework可以减轻docker实施过程中的工作量&#xff0c;在网上也找了几篇类似的文章&#xff0c;按照相应配置&#xff0c;结果并不相同 如下测试过程记录下&#xff1a; docker run -it --rm --name c1 busybox docker run -it --rm --name c2 busyboxpipework br1 c1 192…

玛格全屋定制携手君子签,实现业务信息、流程、合同全面数字化

中国定制家居领导品牌——玛格全屋定制携手君子签&#xff0c;部署玛格业务系统&#xff0c;将电子签章系统与供应链上下游业务合同签署场景融合&#xff0c;通过无纸化、电子化的签署环境&#xff0c;打造业务“线上审批、签署、归档”闭环&#xff0c;助推业务减负提效。 电…

Redis 布隆过滤器

布隆过滤器 这一篇文章主要是记录布隆过滤器的使用和认识 主要参考了如下的blog https://blog.csdn.net/weixin_42972832/article/details/131211665 他讲的还不错 简单的来说,布隆过滤器,实际上就像是一个集合,拿redis的key来举例来说,布隆过滤器的设置就是去过滤不属于redi…

5、混合模型(Hybrid Models)

将两个预测模型的优势结合起来。 文章目录 1、简介2、组件和残差3、混合预测与残差3.1设计混合模型4、示例 - 美国零售销售1、简介 线性回归擅长推断趋势,但不能学习交互。XGBoost擅长学习交互,但不能推断趋势。在这个课程中,我们将学习如何创建"混合"预测器,这…

分割头篇 | 原创自研 | YOLOv8 更换 SEResNeXtBottleneck 头 | 附详细结构图

左图:ResNet 的一个模块。右图:复杂度大致相同的 ResNeXt 模块,基数(cardinality)为32。图中的一层表示为(输入通道数,滤波器大小,输出通道数)。 1. 思路 ResNeXt是微软研究院在2017年发表的成果。它的设计灵感来自于经典的ResNet模型,但ResNeXt有个特别之处:它采用…

BeanFactory创建过程(基于Servlet)

BeanFactory创建过程&#xff08;基于Servlet&#xff09; 1. 概述1.2 那么问题就来了1.2.1 谁负责AnnotationConfigServletWebServerApplicationContext实例呢&#xff1f;1.2.2 ApplicationContextFactory初始化过程又是怎么样的&#xff1f; 1.3 总结 2. 最后 1. 概述 Anno…

【C++零散小记录】类中重载返回类型为常量引用和非常量引用的函数

#include <iostream>class hyp { public://这里后面必须要加上const修饰符&#xff0c;否则这两个test函数不能重载int const& test() const{std::cout << "const" << std::endl;return num;}//int &test()//{// std::cout << &qu…

吉大计网笔记

Osi七层模型 物理层&#xff1a;比特流的透明传输 数据链路层&#xff1a;ip数据包装成帧并传输&#xff0c;处理相邻节点的数据传输。 网络层&#xff1a;选择路由和交换节点&#xff0c;处理任意节点的数据传输。 运输层&#xff1a;主机进程的数据传输服务&#xff0c;端到端…

雷达DoA估计的跨行业应用--麦克风阵列声源定位(Matlab仿真)

一、概述 麦克风阵列&#xff1a; 麦克风阵列是由一定数目的声学传感器&#xff08;麦克风&#xff09;按照一定规则排列的多麦克风系统&#xff0c;而基于麦克风阵列的声源定位是指用麦克风拾取声音信号&#xff0c;通过对麦克风阵列的各路输出信号进行分析和处理&#xff0c;…