通俗易懂多图透彻讲解二叉树的遍历--前序, 中序和后序

二叉树的遍历是一个数据结构中经常会遇到的知识点, 具体又分为前序, 中序和后序三种.

什么是树?

先来理解一下什么是树, 从一个我们相对熟悉的家谱树(Family Tree)说起吧.

数据结构-树-家谱树

家族的根是爷爷, 然后生了两个娃, 大伯和你爸爸. 继续往下, 有堂哥堂姐, 还有你以及你妹, 等等.

一个家族繁衍下来, 很像一棵树开枝散叶, 当然跟真的树相比, 画出来时通常是倒过来的, 根在上面.

二叉树 VS 多叉树

明白了什么是树, 那什么又是二叉树呢?

首先这里每个人称为树的一个节点. 而每个节点下面呢? 可以看到最多只有两个节点.

可能养三个娃太费劲了, 或者计划生育, 顶多两个葫芦娃, 超生了就罚款, 当然现在应该不会了.

一个节点, 在它之下的节点, 多则两个,少则一个甚至没有, 这就是二叉树.

而如果像下边这样, 大伯之后还有个二伯, 你爸是老三, 那这就不算了.

多叉树

所以前面的图是二叉树, 后面的的则不是.

二叉树的节点(Node)

再来看二叉树的几种节点.

二叉树的节点-根节点-左节点-右节点

首先爷爷这里叫做 根节点, 老祖宗.

给他一个绿色, 不是帽子啊. 只是为了区分.

然后一个节点下面不是顶多两个节点嘛, 那左边这个呢就叫 左节点, 标成红色.

这里像大伯, 堂哥, 你还有外甥, 不管处在哪个层级或者说辈分也好, 只要在左边的就是左节点.

那其余的自然就是 右节点 了. 用蓝色表示.

二叉树的子树(subtree)

了解了左右节点后, 再来看一个子树的概念.

二叉树的子树-左子树-右子树

根节点左边这一支呢, 也就是你大伯一家子, 与节点类似, 就叫 左子树, 还是用红色表示.

右边的自然就是 右子树 了, 也就是你爸爸这一家子.

二叉树的遍历(traversal)

有了以上概念后, 再来看遍历. 那什么是遍历呢?

假设来说吧, 有一天你变得很出名, 然后有个好事的记者呢, 就想对你这整个家族的人, 都采访一下, 挖点奇闻轶事或者你小时候的糗事出来.

这种把一个树上全部节点都访问一次的行为, 就是遍历, 都历经一遍.

既然都要访问, 那现在的问题就是, 这里这么多人, 到底按什么顺序去访问.

对于二叉树, 深度优先的遍历有这么三种:

  • 前序遍历(preorder)
  • 中序遍历(inorder)
  • 后序遍历(postorder)

二叉树的前序遍历

先来看什么是前序遍历.

它的大规则或者说大的方向是先访问根节点, 然后是左子树, 最后是右子树. 简称 “根-左-右”.

先采访爷爷. 然后是大伯一家子, 最后到你家.

二叉树前序遍历的大方向

当然这两家子下面又还有很多人, 到底又先采访谁的小规则我们晚点再说.

先说另一个问题, 不知道你想过没有, 为什么大规则要这样安排呢?

二叉树遍历的就近原则

这里介绍二叉树遍历的一个可以叫做就近的原则吧.

假设来说, 这是个地图, 爷爷在江西, 然后子女通常围绕父母就近开枝散叶, 比如大伯就去了临近的广东, 而你爸爸则到了旁边的福建, 这是很自然的.

二叉树遍历的就近原则

再往下呢, 也是类似的, 堂哥堂姐们就随着大伯在广东混了, 而你和你妹自然就在福建, 也是很合理的.

那回到记者采访的问题上, 假如这个记者刚采访完广东的大伯, 又大老远跑到福建去采访你爸爸,
左右横跳, 飞来飞去, 好不容易挣点稿费, 都交给铁道部或者民航局了, 不划算.

另外, 我们可能注意到一点, 大伯和你爸和爷爷之间都有一条线连接.

想象这是一棵树, 而记者则是一只蚂蚁, 他现在在大伯这个节点上, 他要去你爸那边, 其实他要先沿着左边的路爬回到爷爷这个根节点, 再顺着右边的树枝才能爬到你爸的节点上.

大伯和你爸之间其实是没有连线的. 如果有的话, 这就不是树形结构而是图形结构了.

左子树的前序遍历

明白了这个就近原则后, 我们继续看这个左子树里面的节点要按什么顺序去访问.

前面说了大规则是 根-左-右, 然后说子树里面要确定一个小规则. 其实呢, 并不存在所谓的小规则.

当把左子树单拎出来, 其实它还是一颗树. 因此依然可以按照 “根-左-右” 的规则.

先访问根节点, 大伯;

之后是左子树, 堂哥一家子;

最后是右子树, 堂姐, 或者说右节点, 目前就她一个, 可能还没出嫁或者还没生娃.

二叉树左子树的前序遍历

这里利用了子树和整棵树之间的一种自相似特性. 想象一下, 把一棵树的一个树枝掰断了, 插在地上, 它看上去是不是就像一颗小树?

儿子跟老子长得一样, 这就是自相似. 因为存在这种相似性, 就可以重复使用同一个规则, 而不需要针对各个子部分又发明新的规则, 这就是递归处理.

左子树的展开

那么将左子树展开, 爷爷之后是大伯, 然后是堂哥一家, 这个需要继续展开;

二叉树前序遍历-左子树的展开

然后是堂姐, 最后到你家, 也是需要进一步展开.

左子树的继续展开

继续展开堂哥一家, 依然是按照 “根-左-右” 的顺序.

先是堂哥, 然后左子树, 这个大侄子这里没有, 可能因为他太调皮捣蛋了, 堂哥不要他, 让别人抱养走了;

二叉树前序遍历-左子树的继续展开

左子树或者左节点没有就跳过;

最后是右子树, 你侄女, 或者说右节点, 小学刚毕业呢, 还没到合法生娃的年纪, 下面没人了, 所以展开到她这里也结束了.

左子树的完全展开

这样就完全确定了大伯一家子的采访顺序.

二叉树前序遍历-左子树的完全展开

大伯之后是堂哥, 再之后是侄女, 最后是堂姐.

右子树的展开

左子树展开完了, 再看右子树, 那就简单了, 依然是按照 “根-左-右” 的顺序,

二叉树前序遍历-右子树的展开

先是爸爸这个根节点; 然后是左子树, 或者说左节点, 也就是你, 光杆司令一个, 就不用继续展开了; 最后是右子树, 妹妹一家, 需要继续展开.

右子树的继续展开

展开后就是这样.

二叉树前序遍历-右子树的继续展开

先是根节点爸爸, 其次是左节点你, 最后是右子树, 妹妹一家.

右子树的完全展开

最后妹妹一家再展开. 还是 “根-左-右” 的顺序:

二叉树前序遍历-右子树的完全展开

先是根节点, 妹妹; 再到左节点, 你外甥;

然后是右节点, 暂时没有, 还没怀上呢, 或者还没生出来, 还在妈妈肚子里喝羊水呢, 那就也不用管它, 跳过就完了.

至此, 这一大家子人的采访顺序就全部确定了.

二叉树前序遍历-右子树的完全展开

显然, 无论这棵树有多深, 哪怕向天再借500年, 家族不断繁衍, 子又生孙孙又生子, 子又有子子又有孙, 子子孙孙祖宗十八代, 照样可以按照这同一条规则去确定遍历的顺序.

前序遍历的总结

最后, 对前序遍历做个总结.

记住 “根-左-右” 这个顺序. 先是爷爷这个根节点, 然后左子树, 右子树.

二叉树前序遍历-根级别展开

左子树里面, 又继续按照 “根-左-右” 的顺序:

二叉树前序遍历-左子树级别展开

先是大伯这个根节点, 然后左子树, 之后右节点堂姐.

再之后, 堂哥这里, 还是按照 “根-左-右” 的顺序:

二叉树前序遍历-左子树的子树级别展开

当然这时没有左子树, 那跳过就行了, 先是根节点, 然后右节点.

而右子树呢, 也是按照 “根-左-右, 根-左-右” 的顺序不断递归展开, 最终得到了前序遍历下, 所有节点的访问顺序.

二叉树前序遍历-左右子树的全部展开

二叉树的中序遍历

明白了前序遍历后, 再来看中序遍历, 就很容易理解了, 唯一的区别是访问顺序.

中序遍历按照 “左-根-右” 的顺序, 根节点在中间.

二叉树的中序遍历

先是左子树, 堂哥一家子这次排在了最前;

然后才到根节点, 爷爷这里, 处于中间;

最后才是右子树, 也是你爸爸一家.

而每一个子部分呢, 递归地按照 “左-根-右” 的顺序展开, 直到完全展开成我们看到的这个顺序.

在这里, 像爷爷, 大伯, 爸爸这些根节点呢, 大概是处在中间, 或者是每个子部分的中间

那么这就是中序遍历, 也叫中根遍历, 根在中间.

二叉树的后序遍历

最后, 来看下后序遍历, 同样的道理, 只是顺序变成了 “左-右-根”, 根在最后.

读者可自己依葫芦画瓢, 尝试一下展开.

最终结果就是这样, 每一子部分都是按照"左-右-根"的顺序不断展开, 最终许多根节点是相对处在后面的.

二叉树的后序遍历

读者可以核对一下自己展开的结果是否正确. 如果有什么疑问, 可以对照着前面的前序和中序遍历好好理解一下, 举一反三, 因为道理都是类似的, 这里就不再展开那些细节了.

如果你得到了正确的访问顺序, 那可以说你已经正确地掌握了这三种遍历形式.

二叉树的遍历总结

最后是对二叉树这三种遍历的一个总结.

  • 前序, 又叫 前根遍历, 按照 “根-左-右” 的顺序递归展开;
  • 中序, 又叫 中根遍历, 按照 “左-根-右” 的顺序递归展开;
  • 后序, 又叫 后根遍历, 按照 “左-右-根” 的顺序递归展开;

所以, 主要区别就在根的位置上.

二叉树的前根, 中根和后根遍历顺序总结

  1. 首先, 前中后指的就是根的位置.
  2. 其次, 左右子树则始终是先左后右.
  3. 最后, 递归应用以上规则直到子树全部展开.

关于二叉树的前序, 中序和后序这三种遍历方式就讲到这里, 谢谢大家.

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

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

相关文章

简化流程,强化协作——揭秘可道云TeamOS文档审批的实用魅力

在团队协作的过程中,文档审批是确保信息安全和流程规范的重要环节。然而,传统的文档审批流程往往繁琐且僵化,难以满足团队快速响应和灵活协作的需求。 可道云teamOS的文档审批功能,以其独特的灵活性和便捷性,为团队带…

java——Junit单元测试

测试分类 黑盒测试:不输入代码,给输入值,看程序能够给出期望的值。 白盒测试:写代码,关注程序具体执行流程。 JUnit单元测试 一个测试框架,供java开发人员编写单元测试。 是程序员测试,即白…

PBT激光穿透率测量仪

在现代材料科学与工业制造领域,激光技术以其高精度、高效率和非接触性等特点,成为了不可或缺的测量与加工手段。其中,PBT(聚对苯二甲酸丁二醇酯)作为一种重要的热塑性工程塑料,因其优异的机械性能、耐热性和…

嵌入式全栈设计思路:STM32G4+ChibiOS+FreeRTOS+PID控制+PFC算法构建高效智能电源管理系统(附代码示例)

智能电源管理系统是一个基于STM32G4微控制器的高性能数字电源控制解决方案。本项目旨在设计一个功能全面、高效稳定的电源管理系统,可广泛应用于工业控制、新能源、通信设备等领域。 1.1 系统主要特点 高精度数字电源控制:利用STM32G4的高性能ADC和定时器,实现精确…

HTML5+CSS3小实例:纯CSS实现奥运五环

实例:纯CSS实现奥运五环 技术栈:HTML+CSS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-sca…

网页数据抓取:融合BeautifulSoup和Scrapy的高级爬虫技术

网页数据抓取&#xff1a;融合BeautifulSoup和Scrapy的高级爬虫技术 在当今的大数据时代&#xff0c;网络爬虫技术已经成为获取信息的重要手段之一。Python凭借其强大的库支持&#xff0c;成为了进行网页数据抓取的首选语言。在众多的爬虫库中&#xff0c;BeautifulSoup和Scrap…

在Android Jetpack Compose中实现夜间模式

在Android Jetpack Compose中实现夜间模式 随着用户对夜间模式需求的增加,Android开发者需要掌握如何在应用中实现这一功能。Jetpack Compose作为现代Android UI工具包,提供了简便且灵活的方式来实现夜间模式。本文将详细介绍如何在Jetpack Compose中实现夜间模式,包括配置…

Linux系统之玩转fortune命令

Linux系统之好玩的fortune命令 一、fortune命令介绍1.1 fortune简介1.2 fortune中英文 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本 四、fortune英文版的使用4.1 安装fortune英文版4.2 命令帮助4.3 fortu…

安卓手机刷入Magisk面具教程

手机如果想获取 Root 权限&#xff0c;刷入面具是必要的做法。本期文章将会教你如何刷入 Magisk 面具。 准备工作 Magisk: 关注微信公众号 heStudio Community回复 magisk 获取下载链接。第三方 Recovery&#xff08;官方 Recovery 能玩出什么花样&#xff1f;&#xff1f;&a…

PDM系统:企业产品数据管理、PDM系统哪个好

PDM系统&#xff1a;企业产品数据管理、PDM系统哪个好 在当今这个数据驱动的时代&#xff0c;企业产品数据管理&#xff08;PDM&#xff09;系统已成为企业提升竞争力、加速产品创新、优化生产流程的关键工具。PDM系统不仅是一个技术平台&#xff0c;更是企业实现数字化转型的重…

防火墙负载分担,带宽策略

一、实验拓扑图 二、实验要求 12&#xff0c;对现有网络进行改造升级&#xff0c;将当个防火墙组网改成双机热备的组网形式&#xff0c;做负载分担模式&#xff0c;游客区和DMZ区走FW3&#xff0c;生产区和办公区的流量走FW1 13&#xff0c;办公区上网用户限制流量不超过100M&a…

昇思25天学习打卡营第23天|基于MobileNetv2的垃圾分类

基于MobileNetv2的垃圾分类 1、实验目的 了解熟悉垃圾分类应用代码的编写&#xff08;Python语言&#xff09;&#xff1b;了解Linux操作系统的基本使用&#xff1b;掌握atc命令进行模型转换的基本操作。 2、MobileNetv2模型原理介绍 MobileNet网络是由Google团队于2017年提…

效能工具:执行 npm start 可直接切换proxy代理UR后直接启动项目

1) 背景: 我们项目是2个前端3个后端的配置。前端和每个后端都有需要调试的接口。 因此经常切换vite.congig.js中的proxy后端代理链接&#xff0c;是挺麻烦的。 于是我研究如何能快速切换后端URL&#xff0c;所幸懒人有懒福&#xff0c;我找到了Inquirer 和 fs&#xff0c; 实…

根据日志绘制障碍物轮廓点和中心点

绘制log中的障碍物凸包点&#xff0c;首先给出log日志中的障碍物的凸包点 [Info]-[PointCloudHandle:88]:[2024-07-14,09:55:41.052]-back obj size 6 [Info]-[PointCloudHandle:92]:[2024-07-14,09:55:41.052]-back obj size 6 cur idx 1 [Info]-[PointCloudHandle:93]:[2024…

STM32+TMC2209控制步进电机正反转。

STM32F103ZET6TMC2209控制步进电机正反转 1. 步进电机介绍2 驱动器TMC2209介绍2.1 引脚图及其功能2.2 细分介绍2.3 TMC控制驱动器接法 3 控制器介绍3.1 确定控制引脚3.2 UBEMX配置3.2.1 GPIO配置3.2.2 NVIC配置3.2.3 RCC配置3.2.4 SYS配置3.2.5 USRAT2配置&#xff08;PS:没用上…

单相电机或风扇接电容的具体接线方法示例

单相电机或风扇接电容的具体接线方法示例 如下图所示&#xff0c;单相电机引出3根绕组线&#xff08;不同品牌或型号的电机&#xff0c;引出线的颜色可能会有差异&#xff09;&#xff0c; 那么如何进行接线呢&#xff1f; 首先&#xff0c;跳过万用表测量主、副绕组的阻值…

Unable to obtain driver using Selenium Manager: Selenium Manager failed解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

【Linux】Ubuntu 漏洞扫描与修复的吃瘪经历

自从上次“劫持”事情后&#xff0c;项目经理将所有跟安全相关的都推给我了&#xff08;不算 KPI 又要被白嫖&#xff0c;烦死了&#xff09;。这次客户又提了一个服务器安全扫描和漏洞修复的“活”&#xff0c;我这边顺手将过程记录一下&#xff0c;就当经验总结跟各位分享一下…

【Linux】多线程_7

文章目录 九、多线程8. POSIX信号量根据信号量环形队列的生产者消费者模型代码结果演示 未完待续 九、多线程 8. POSIX信号量 POSIX信号量和SystemV信号量作用相同&#xff0c;都是用于同步操作&#xff0c;达到无冲突的访问共享资源目的。 但POSIX可以用于线程间同步。 创建…