中序遍历二叉树全过程图解

文章目录

  • 中序遍历图解
  • 总结

中序遍历图解

在这里插入图片描述

首先看下中序遍历的代码,其接受一个根结点root作为参数,判断根节点是否为nil,不为nil则先递归遍历左子树。

func traversal(root *TreeNode,res *[]int)  {if root == nil {return}traversal(root.Left,res)*res = append(*res,root.Val)traversal(root.Right,res)
}

我们把树根结点A传递给它,其左结点为B,右结点为C

首先我们要检查root是否为nil,其不为nil,通过递归继续遍历左边的子树,将左子树传递给递归函数,该层递归函数的rootB,其左子树为D 右子树为E,判断root是否为nilroot不为nil,继续将该树的左子树向下递归,该层递归函数的rootD,左右子树都为nil,我们检查root是否为nilrootD,不为nil,继续递归遍历D的左子树,其左子树为nil,所以该层递归函数的rootnil满足递归结束条件,执行return退出该层递归函数

到此处时的运行栈如下图所示
在这里插入图片描述

此时的return会回到rootD的递归层,D的左子树已经遍历完毕,我们执行下一行语句append
该语句会将root的数据域加入到结构列表res中,即访问到了D,如下图
在这里插入图片描述

按照顺序继续执行,接下来将使用递归遍历D的右子树,这里D的右子树为nil,所以我们传入的递归参数也为nil,检测到rootnil,我们退出该层递归函数,回到调用层D,该层的所有语句都执行完毕了。我们继续回到调用它的函数,即B层的 traversal(root.Left,res)语句处

在这里插入图片描述

继续执行后序语句,执行 *res = append(*res,root.Val)记录root的数据域,即访问B,再执行下一条语句
递归访问B的右子树,将E传递给它,判断root是否为nilrootE,不为nil,递归调用E的左子树,左子树为nil,判断root是否为nil,为nil,退出该层
在这里插入图片描述
执行下一行,将E记录到结果中,继续遍历E的右子树,右子树为nil,直接退出该层递归函数,返回到了E的递归层,E这层也执行完毕了,返回到调用它的B
在这里插入图片描述

随即B层也执行完了,返回到调用它的A层 ,在该层执行下一行代码,将A记录到结果中,继续遍历A的右子树,A的右子树为C,其不为nil,递归C的左子树FF不为nil,递归F的左子树,F的左子树为nil,即传入的rootnil,满足递归结束条件,开始回归上层。
在这里插入图片描述

返回到调用它的F层,将F记录到结果中。遍历F的右子树,F的右子树也为nil,退出该层,到此F这层函数执行完毕,返回到调用F的递归层 C,下一行语句记录C
在这里插入图片描述

继续下一行语句,递归C的右子树G,判断该层递归的root是否为nil,当前rootG,不为nil,递归G的左子树,左子树为nil,满足递归结束条件,返回到调用它的G,输出G,递归G的右子树,右子树为nil
满足递归结束条件,返回到调用它的GG这层函数结束,返回上层到C

C也运行完毕,返回上层到AA也运行完毕,此该树递归结束,这样我们就得到了中序遍历序列

总结

再次回顾一下代码

func traversal(root *TreeNode,res *[]int)  {if root == nil {return}traversal(root.Left,res)*res = append(*res,root.Val)traversal(root.Right,res)
}

从我们的遍历全流程图解来看,不难理解,每个节点都是将其左子树全部递归遍历完后,才开始遍历其右子树的,如根节点A,是将其左子树BDE全部遍历完后,才开始遍历右子树的,注意思考递归栈哦,这样才能真正的理解。

中序遍历理解后,前序和后续遍历是一样的道理。这时一起看下后续遍历的代码:

func traversal(root *TreeNode,res *[]int)  {if root == nil {return}traversal(root.Left,res)traversal(root.Right,res)*res = append(*res,root.Val)
}

很多同学看到递归左右子树的那两行代码,很容易陷入误区,以为那两行是"同时"在执行,认为遍历完root的左节点后,立马遍历了其右节点,这种理解是非常不对的,实际是遍历完整个左子树后,经过回到当前层,此时才会开始执行当前层的traversal(root.Right,res)语句去遍历右子树。

尤其是看到两条回溯语句写在同一行时会更容易误解,如力扣104. 二叉树的最大深度

/*** definition for a binary tree node.* type treenode struct {*     val int*     left *treenode*     right *treenode* }*/
func max (a, b int) int {if a > b {return a}return b
}// 递归
func maxdepth(root *treenode) int {if root == nil {return 0}return max(maxdepth(root.left), maxdepth(root.right)) + 1
}

实际最后一行代码是简化版,等价于如下代码

/*** definition for a binary tree node.* type treenode struct {*     val int*     left *treenode*     right *treenode* }*/
func max (a, b int) int {if a > b {return a}return b
}// 递归
func maxdepth(root *treenode) int {if root == nil {return 0}leftDepth := maxdepth(root.left) // 递归左子树的深度rightDepth := maxdepth(root.right) // 递归右子树的深度return max(leftDepth,rightDepth ) + 1 // 当前根节点到叶子节点的最大深度
}

此时再看此代码是不是好理解一些 ,它就是我们的后序遍历哇!将左子树全部遍历完后,才会开始遍历右子树,最后则是根节点,然后回到上层调用栈,直到所有接地那遍历完毕,递归函数执行完毕。

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

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

相关文章

华为HarmonyOS地图服务 5 - 利用UI控件和手势进行地图交互

场景介绍 本章节将向您介绍如何使用地图的手势。 Map Kit提供了多种手势供用户与地图之间进行交互,如缩放、滚动、旋转和倾斜。这些手势默认开启,如果想要关闭某些手势,可以通过MapComponentController类提供的接口来控制手势的开关。 接口说明 以下是地图的控件和手势相…

【LLM多模态】文生视频评测基准VBench

note VBench的16个维度自动化评估指标代码实践(待完成)16个维度的prompt举例人类偏好标注:计算VBench评估结果与人类偏好之间的相关性、用于DPO微调 文章目录 note一、相关背景二、VBench评测基准概述:论文如何解决这个问题&…

Java免税购物商城:Spring Boot技术实现

第二章 系统开发关键技术 2.1 JAVA技术 Java主要采用CORBA技术和安全模型,可以在互联网应用的数据保护。它还提供了对EJB(Enterrise JavaBeans)的全面支持,java servlet AI,JS(java server ages&#xff09…

RNN的反向传播

目录 1.RNN网络:通过时间反向传播(through time back propagate TTBP) 2.RNN梯度分析 2.1隐藏状态和输出 2.2正向传播: 2.3反向传播: 2.4问题瓶颈: 3.截断时间步分类: 4.截断策略比较 5.反向传播的细节 ​编辑…

植物病害识别系统Python+卷积神经网络算法+图像识别+人工智能项目+深度学习项目+计算机课设项目+Django网页界面

一、介绍 植物病害识别系统。本系统使用Python作为主要编程语言,通过收集水稻常见的四种叶片病害图片(‘细菌性叶枯病’, ‘稻瘟病’, ‘褐斑病’, ‘稻瘟条纹病毒病’)作为后面模型训练用到的数据集。然后使用TensorFlow搭建卷积神经网络算…

【后端开发】JavaEE初阶—线程的理解和编程实现

前言: 🌟🌟本期讲解多线程的知识哟~~~,希望能帮到屏幕前的你。 🌈上期博客在这里:【后端开发】JavaEE初阶——计算机是如何工作的???-CSDN博客 🌈感兴趣的小伙…

Tomcat中BIO和NIO的区别(Tomcat)

BIO Tomcat中BIO的模型和理论很简单,例图如下 1.Acceptor线程死循环阻塞接收客户端的打过来的socket请求 2.接收到请求之后打包成一个SocketProcessor(Runnable),扔到线程池中读取/写入数据 参数配置 1.Acceptor默认线程是1&#…

【Godot4.x】Mesh相关知识总结

概述 很早之前发布过一篇关于几何体程序生成的文章,当时对于三角面和网格的构造其实还没有特别深入的认识,直到自己脑海里想到用二维数组和点更新的方式构造2D类型的多边形Mesh结构,也意识到在Godot中其实Mesh不仅是3D网格,也可以…

分子动力学工具篇二:Sobtop的安装与使用

文章目录 1. Sobtop的介绍1. Sobtop 的功能和特点2.主要应用场景 2.3.常见问题及解决方法 1. Sobtop的介绍 Sobtop 是一个用于自动生成分子拓扑文件的工具,特别是为 GROMACS 分子动力学模拟准备拓扑结构和参数。它的设计目标是通过自动化过程生成小分子、聚合物或其…

msvcp140.dll0丢失的解决方法,总结6种靠谱的解决方法

再使用计算机的过程中,我们经常会遇到一些错误提示,其中之一就是“msvcp140.dll丢失”。这个问题可能会影响到我们的正常使用,因此需要及时解决。经过一段时间的学习和实践,我总结了以下六种靠谱的解决方法,希望对大家…

Flask-WTF的使用

组织一个 Flask 项目通常需要遵循一定的结构,以便代码清晰、可维护。下面是一个典型的 Flask 项目结构: my_flask_app/ │ ├── app/ │ ├── __init__.py │ ├── models.py │ ├── views.py │ ├── forms.py │ ├── templat…

【HTTP】构造HTTP请求和状态码

状态码 用于响应中,表示响应的结果如何 正确?错误?什么原因? HTTP 中的状态码都是标准约定好的 200 OK 成功了,一切顺利 在抓包到的响应中 404 Not Found 访问的资源(URL 中的路径)没找…

数据结构之线性表——LeetCode:707. 设计链表,206. 反转链表,92. 反转链表 II

707. 设计链表 题目描述 707. 设计链表 你可以选择使用单链表或者双链表,设计并实现自己的链表。 单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。 如果是双向链表,则…

小程序——生命周期

文章目录 运行机制更新机制生命周期介绍应用级别生命周期页面级别生命周期组件生命周期生命周期两个细节补充说明总结 运行机制 用一张图简要概述一下小程序的运行机制 冷启动与热启动: 小程序启动可以分为两种情况,一种是冷启动,一种是热…

低代码门户技术:构建高效应用的全新方式

什么是低代码门户技术? 低代码门户技术是一种利用低代码平台构建企业门户网站或应用的技术。门户通常是企业内部和外部用户访问信息和应用的集中平台。低代码门户技术通过图形化界面和预置组件,允许用户快速搭建和定制这些门户平台,而无需深…

CefSharp_Vue交互(Element UI)_WinFormWeb应用(3)---通过页面锁屏和关机(含示例代码)

一、预览 实现功能:通过vue标题栏按钮锁屏和关机 1.1 预览 1.2 代码 锁屏代码csharp LockWorkStation() 关机代码chsharp 注意vue代码参数和此参数一致(0/1/2) 方法ExitWindowsEx()

mac电脑打不开rar文件怎么办 rar文件怎么转换成zip并打开

rar文件是一种常见的压缩文件格式,它可以将多个文件或文件夹打包成一个文件,从而节省空间和方便传输。但是,mac系统并没有自带的工具可以直接打开或解压rar文件,那么,mac用户该如何处理rar文件呢? 一、mac电…

初步认识C++模版

前言 在C语言中,我们知道函数的形参需要指定类型,但是在C中,我们可以模版实现各种类型参数的通用函数。 1. 泛型编程 我们通过函数重载实现多种类型的同一作用的函数。如交换函数: void Swap(int& left, int& right) …

微信getUserProfile不弹出授权框

当我们在微信小程序开发工具中想要使用getUserProfile来获取个人信息的时候,会发现不弹出授权框,这是什么原因呢? 早在2022年的小程序官方公告中就已经明确给出了小程序用户头像昵称获取规则调整公告 因此如果还想继续使用getUserProfile的弹…

功能测试干了三年,快要废了。。。

8年前刚进入IT行业,到现在学习软件测试的人越来越多,所以在这我想结合自己的一些看法给大家提一些建议。 最近聊到软件测试的行业内卷,越来越多的转行和大学生进入测试行业,导致软件测试已经饱和了,想要获得更好的待遇…