二叉树的层序遍历(含十道leetcode相关题目)

news2024/9/21 0:46:30

文章目录

  • 二叉树层序遍历模板
  • 102. 二叉树的层序遍历

二叉树层序遍历模板

我们之前讲过了关于二叉树的深度优先遍历的文章:前中后序遍历的递归法和迭代法。

接下来我们再来介绍二叉树的另一种遍历方式:层序遍历

层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。

需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。

而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。

在这里插入图片描述
如图所示:将每层的元素从左至右加入队列,取出时就会先取出左节点,并将当前节点的左右节点又加入队尾,接着从队列取出下一个元素,将它的左右节点同样加入队尾,以此类推。那怎么确认取出多少个元素的时候可认为当前层的元素都取完了呢?这就需要一个变量来记录啦,这个变量其实就是每轮循环开始时队列的长度,当前长度就是当前层的所有元素,该轮循环的后续操作就是将下一层的所有节点加入队尾。

这样就实现了层序从左到右遍历二叉树。

代码如下:这份代码也可以作为二叉树层序遍历的模板,打十个就靠它了。

Go代码如下

102. 二叉树的层序遍历

迭代法

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func levelOrder(root *TreeNode) [][]int {
    if root == nil {
        return [][]int{}
    }

    res := make([][]int,0)
    queue := make([]*TreeNode,0)
    queue = append(queue,root)
    for len(queue) != 0 {
        // 当前层的元素个数,以及定义存当前层结果的数组
        queueSize := len(queue)
        curLevelRes := make([]int,0)
        // 取出当前层所有元素,并依次加入下一层的元素
        for i := 0; i < queueSize ;i++ {
            curNode := queue[0]
            queue = queue[1:len(queue)]
            curLevelRes = append(curLevelRes,curNode.Val)
            // 当前节点的左右节点加入队列
            if curNode.Left != nil {
                queue = append(queue,curNode.Left)
            }
            if curNode.Right != nil {
                queue = append(queue,curNode.Right)
            }
        }
        // 当前层遍历完成,将当前层结果加入最终结果中
        res = append(res,curLevelRes)
    }

    return res
}

递归法

// 层序遍历递归法
func levelOrder(root *TreeNode) [][]int {
    if root == nil {
        return [][]int{}
    }

    res := make([][]int,0)
    preOrder(root,0,&res) //根节点在第0层

    return res
}

/*直接使用二叉树的前序遍历的递归形式即可,只是递归的时候,要多传一个参数,
 就是该节点属于第几层的,很简单,子节点所在层数是父节点所在层数加一*/
func preOrder(node *TreeNode,level int,res *[][]int) {
    //如果level是新层,则在res中继续添加一个[]int用于存这一次的结点的值
    if len(*res) == level {
        culLevelRes := make([]int,0)
        *res = append(*res,culLevelRes)
    }

    //将结点的值添加到res中对应的层的[]int中
    (*res)[level] = append((*res)[level],node.Val)
    //递归遍历左右子节点
    if node.Left != nil {
        preOrder(node.Left,level + 1,res)
    }
    if node.Right != nil {
        preOrder(node.Right,level + 1,res)
    }
}

在这里插入图片描述

102. 二叉树的层序遍历

102. 二叉树的层序遍历

给你二叉树的根节点 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

Go 代码迭代法

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func levelOrder(root *TreeNode) [][]int {
    if root == nil {
        return [][]int{}
    }

    res := make([][]int,0)
    queue := make([]*TreeNode,0)
    queue = append(queue,root)
    for len(queue) != 0 {
        // 当前层的元素个数,以及定义存当前层结果的数组
        queueSize := len(queue)
        curLevelRes := make([]int,0)
        // 取出当前层所有元素,并依次加入下一层的元素
        for i := 0; i < queueSize ;i++ {
            curNode := queue[0]
            queue = queue[1:len(queue)]
            curLevelRes = append(curLevelRes,curNode.Val)
            // 当前节点的左右节点加入队列
            if curNode.Left != nil {
                queue = append(queue,curNode.Left)
            }
            if curNode.Right != nil {
                queue = append(queue,curNode.Right)
            }
        }
        // 当前层遍历完成,将当前层结果加入最终结果中
        res = append(res,curLevelRes)
    }

    return res
}

在这里插入图片描述

Go代码递归法

// 层序遍历递归法
func levelOrder(root *TreeNode) [][]int {
    if root == nil {
        return [][]int{}
    }

    res := make([][]int,0)
    preOrder(root,0,&res) //根节点在第0层

    return res
}

/*直接使用二叉树的前序遍历的递归形式即可,只是递归的时候,要多传一个参数,
 就是该节点属于第几层的,很简单,子节点所在层数是父节点所在层数加一*/
func preOrder(node *TreeNode,level int,res *[][]int) {
    //如果level是新层,则在res中继续添加一个[]int用于存这一次的结点的值
    if len(*res) == level {
        culLevelRes := make([]int,0)
        *res = append(*res,culLevelRes)
    }

    //将结点的值添加到res中对应的层的[]int中
    (*res)[level] = append((*res)[level],node.Val)
    //递归遍历左右子节点
    if node.Left != nil {
        preOrder(node.Left,level + 1,res)
    }
    if node.Right != nil {
        preOrder(node.Right,level + 1,res)
    }
}

在这里插入图片描述

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

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

相关文章

vue2使用npm引入依赖(例如axios),报错Module parse failed: Unexpected token解决方案

报错情况 Module parse failed: Unexpected token (5:2) You may need an appropriate loader to handle this file type. 原因 因为我们npm install时默认都是下载最新版本&#xff0c;然后个别依赖的版本太新&#xff0c;vue2他受不起这个福分。 解决方法 先去package.js…

SD-WAN如何保障企业数据安全?

SD-WAN&#xff08;软件定义广域网&#xff09;作为一种现代化网络解决方案&#xff0c;不仅能够优化和管理广域网的连接&#xff0c;还集成了一系列安全功能&#xff0c;帮助企业保护其数据安全。以下将详细介绍SD-WAN如何有效保障企业数据安全的机制。 在采用SD-WAN技术之前&…

[论文笔记]MRRNET

这是一篇河大的论文 感觉跟SANET很像 摘要 摘要&#xff1a;随着物联网&#xff08;IoT&#xff09;的大规模部署&#xff0c;道路场景中实时感知和环境理解的需求变得越来越迫切。 同时&#xff0c;语义分割作为像素级场景解析得到了广泛的研究。 然而&#xff0c;资源有限…

合宙Air201模组LuatOS:PWRKEY控制,一键解决解决关机难问题

不知不觉间&#xff0c;我们已经发布拉期课程&#xff1a;hello world初体验&#xff0c;点灯、远程控制、定位和扩展功能&#xff0c;你学的怎么样&#xff1f;很多伙伴表示已经有点上瘾啦&#xff01;合宙Air201&#xff0c;如同我们一路升级打怪的得力法器&#xff0c;让开发…

打通最后一公里:使用CDN加速GitHub Page的访问

无论是互联网从业者还是科研人员&#xff0c;使用Github Page能够很友好的建立个人网站。 目前比较主流的方案是使用GitHub Page托管文字网页&#xff0c;利用GitHub仓库托管图床&#xff0c;稳定可靠&#xff08;Gitee的page突然撤退&#xff0c;让人不敢再将图床放到上面&am…

大数据-138 - ClickHouse 集群 表引擎详解3 - MergeTree 存储结构 数据标记 分区 索引 标记 压缩协同

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

Linux上Qt安装相关的内容及在QtCreator使用QChart模块需要的配置

引言 下面是Ubuntu上Qt安装相关的内容及在QtCreator使用QChart模块需要的配置。 关于Qt安装及环境 Qt的模块 查看已经安装的模块 sudo apt search qt5-安装新的模块 sudo apt install qt5-svg # 安装Qt SVG模块3.查看qt已经安装了哪些模块 dpkg -l | grep libqt安装qt,…

【深度学习实战—11】:基于Pytorch实现谷歌QuickDraw数据集的下载、解析、格式转换、DDP分布式训练、测试

✨博客主页&#xff1a;王乐予&#x1f388; ✨年轻人要&#xff1a;Living for the moment&#xff08;活在当下&#xff09;&#xff01;&#x1f4aa; &#x1f3c6;推荐专栏&#xff1a;【图像处理】【千锤百炼Python】【深度学习】【排序算法】 目录 &#x1f63a;〇、仓库…

链式前向星建图

回顾邻接局矩阵和邻接表建图&#xff1a; ​ 在之前的图论基础中&#xff0c;我们提到了两种建图方式&#xff1a;邻接矩阵、邻接表。 邻接矩阵实现&#xff1a; int N; //所有节点个数 int Graph[N][N]; for(int i : Numbers){ //Numbers表示所有节点for(int j : Neighbor…

VC++以资源方式打开可执行文件

刚看一个资料说可以在VC中&#xff0c;以资源方式打开可执行文件&#xff0c;然后它如果包含对话框一些资源&#xff0c;会呈现出来&#xff0c;可以把其他程序界面上的控件直接拷贝到自己程序&#xff1b; 但是操作了一下没有成功&#xff0c; 先新建一个空对话框准备拷贝东…

【Linux】Linux的基本指令(1)

A clown is always a clown.&#x1f493;&#x1f493;&#x1f493; 目录 ✨说在前面 &#x1f34b;知识点一&#xff1a;Linux的背景 •&#x1f330;1.Unix发展的历史 •&#x1f330;2.Linux发展历史 •&#x1f330;3.企业应用现状 •&#x1f330;4.发行版本 &…

【protobuf】ProtoBuf的学习与使用⸺C++

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 前言&#xff1a;之前我们学习了Linux与windows的protobuf安装&#xff0c;知道protobuf是做序列化操作的应用&#xff0c;今天我们来学习一下protobuf。 目录 ⼀、初识ProtoBuf 步骤1&#xff1a;创建.proto文件 步…

WLAN无线局域网

目录 概述 IEEE 802.11标准与WiFi的世代 ​编辑 无线控制器AC&#xff08;Access Controller&#xff09; 无线接入点AP&#xff08;Access Point&#xff09; PoE&#xff08;Power Over Ethernet&#xff09; PoE交换机 STA&#xff08;Station&#xff09; BSS&#x…

简单生活的快乐

小明经常会被问到一个问题&#xff1a;为什么他那么有钱却选择过一种简单、谦逊的生活。先从小明的早年经历说起吧&#xff0c;大概是他六到十三岁的时候&#xff0c;物质对他来说是非常重要的。他记得当妈妈给他买了一双昂贵的鞋子时&#xff0c;他特别兴奋&#xff0c;喜欢向…

GEE 案例:利用sentinel-2数据计算的NDVI指数对比植被退化情况

目录 简介 NDVI指数 数据 函数 ui.Chart.image.series(imageCollection, region, reducer, scale, xProperty) Arguments: Returns: ui.Chart 代码 结果 简介 利用sentinel-2数据计算的NDVI指数对比植被退化情况 NDVI指数 NDVI&#xff08;Normalized Difference Ve…

武器检测系统源码分享

武器检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

压力测试Monkey命令参数和报告分析!

adb的操作命令格式一般为&#xff1a;adb shell monkey 命令参数 PART 01 常用参数 ⏩ -p <测试的包名列表> 用于约束限制&#xff0c;用此参数指定一个或多个包。指定包之后&#xff0c;Monkey将只允许系统启动指定的APP。如果不指定包&#xff0c;Monkey将允许系统…

【JVM】垃圾回收机制|死亡对象的判断算法|垃圾回收算法

思维导图 目录 1.找到谁是垃圾 1&#xff09;引用计数&#xff08;不是JVM采取的方式&#xff0c;而是Python/PHP的方案&#xff09; 2&#xff09;可达性分析&#xff08;是JVM采用的方案&#xff09; 2.释放对应的内存的策略 1&#xff09;标记-清除&#xff08;并不实…

信息安全数学基础(18)模重复平方计算法

前言 模重复平方计算法&#xff08;Modular Exponentiation by Squaring&#xff09;&#xff0c;也称为快速幂算法&#xff0c;是一种用于高效计算 abmodn 的算法&#xff0c;其中 a、b 和 n 是整数&#xff0c;且 b 可能非常大。这种算法通过减少乘法操作的次数来加速计算过程…

伦敦金的交易差价意味着什么?

在伦敦金投资市场上&#xff0c;点差是指交易平台的买入价&#xff08;买价&#xff09;和卖出价&#xff08;卖价&#xff09;之间的差额。对投资者来说&#xff0c;点差是交易成本的一部分&#xff0c;但它是经纪商的收入来源。点差代表伦敦金投资者在进入和退出交易时需要支…