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

news2024/12/23 5:20:12

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

什么是树?

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

数据结构-树-家谱树

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

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

二叉树 VS 多叉树

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

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

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

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

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

多叉树

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

二叉树的节点(Node)

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

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

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

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

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

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

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

二叉树的子树(subtree)

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

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

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

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

二叉树的遍历(traversal)

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

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

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

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

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

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

二叉树的前序遍历

先来看什么是前序遍历.

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

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

二叉树前序遍历的大方向

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

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

二叉树遍历的就近原则

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

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

二叉树遍历的就近原则

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

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

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

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

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

左子树的前序遍历

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

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

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

先访问根节点, 大伯;

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

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

二叉树左子树的前序遍历

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

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

左子树的展开

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

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

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

左子树的继续展开

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

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

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

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

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

左子树的完全展开

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

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

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

右子树的展开

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

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

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

右子树的继续展开

展开后就是这样.

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

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

右子树的完全展开

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

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

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

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

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

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

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

前序遍历的总结

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

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

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

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

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

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

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

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

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

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

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

二叉树的中序遍历

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

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

二叉树的中序遍历

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

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

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

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

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

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

二叉树的后序遍历

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

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

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

二叉树的后序遍历

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

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

二叉树的遍历总结

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

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

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

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

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

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

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

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

相关文章

工业智能网关的边缘计算能力赋能工业4.0

边缘计算是将数据处理和分析能力推向网络边缘的技术,使得终端设备能够实时、快速地响应环境变化,并做出相应决策。在智能制造中,通过5G工业网关的边缘计算能力,企业可以实现对生产线上大量传感器数据的实时采集、处理和分析&#…

Linux0715

一切皆文件,文件IO已经学习完毕,这两天完成一个minishell的小项目 文件操作 1. 标准IO 具有缓冲区 是对普通文件的读写 1. fopen ----------------------------->文件流指针 FILE * …

联发科又放大招,天玑9400支持10.7Gbps LPDDR5X内存性能拉满!

三星官方消息称,联发科天玑9400将支持全球最快的手机内存10.7Gbps LPDDR5X!而且数码达人科技九州君也在微博上透露,天玑9400将首发支持全球最快的移动DRAM。顶级的内存加上天玑9400采用的黑鹰架构和配置的大CPU缓存,性能直接拉满了…

基于springboot和mybatis的RealWorld后端项目实战三之添加swagger

pom.xml添加依赖 <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.springfox</groupId><arti…

基于python的层次聚类

目录 一、层次聚类概述 二、凝聚法&#xff08;Agglomerative Clustering&#xff09; 1. 初始化 2. 计算距离 3. 合并簇 4. 重复迭代 三、分裂法&#xff08;Divisive Clustering&#xff09; 1. 初始化 2. 分裂簇 3. 分配样本点 4. 重复迭代 四、其他考虑因素 五、总结 …

51、数据库的概念及sql语句

1、数据库 1.1、数据库管理&#xff1a; sql语句 数据库用来增删改查的语句。重要* 备份 数据库的数据进行备份。 主从复制&#xff0c;读写分离 高可用。重要*&#xff0c;原理–面试。 数据库的概念、语法和规范 1.2、数据库的定义 数据库&#xff1a;组织&#xff0c…

ACL实验

目录 一、实验拓扑​编辑 二. 实验要求&#xff08;在图中&#xff09; 三、实验思路 配IP 全网可达 创建模拟机pc1 创建telent r1 r2 由题目可得 截图 pcr1​编辑 pcr2​编辑 四、实验总结&#xff08;写实验完成后的总结心得&#xff09; 一、实验拓扑 二. 实验…

硅纪元AI应用推荐 | 精准识别用户意图,夸克真AI搜索引擎

“硅纪元AI应用推荐”栏目&#xff0c;为您精选最新、最实用的人工智能应用&#xff0c;无论您是AI发烧友还是新手&#xff0c;都能在这里找到提升生活和工作的利器。与我们一起探索AI的无限可能&#xff0c;开启智慧新时代&#xff01; 在数字化时代&#xff0c;搜索引擎成为我…

本地多模态看图说话-llava

其中图片为bast64转码&#xff0c;方便json序列化。 其中模型llava为本地ollama运行的模型&#xff0c;如&#xff1a;ollama run llava 还有其它的模型如&#xff1a;llava-phi3&#xff0c;通过phi3微调过的版本。 实际测试下来&#xff0c;发现本地多模型的性能不佳&…

EasyPoi一对多excel表格导出

效果如下图&#xff1a; 1、引入pom文件 <!--easypoi 一对多导入导出 --> <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>4.2.0</version> </dependency> <dependenc…

AIGC降痕实战:论文降AI率的深度解析与应用

随着AI技术的飞速发展&#xff0c;AI论文工具正逐渐成为学术界的新宠。它们以高效、便捷的优势&#xff0c;吸引了众多学者的目光。然而&#xff0c;随之而来的学术诚信与原创性问题&#xff0c;也成为人们关注的焦点。 如何在享受AI带来的便利的同时&#xff0c;确保论文的原…

pear-admin-fast项目修改为集成PostgreSQL启动

全局搜索代码中的sysdate()&#xff0c;修改为now() 【前者是mysql特有的&#xff0c;后者是postgre特有的】修改application-dev.yml中的数据库url使用DBeaver把mysql中的数据库表导出csv&#xff0c;再从postgre中导入csv脚本转换后出现了bpchar(xx)类型&#xff0c;那么一定…

《数字通信世界》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《数字通信世界》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的第二批认定学术期刊。 问&#xff1a;《数字通信世界》级别&#xff1f; 答&#xff1a;国家级。主管单位&#xff1a;工业和信息化部 主办单位&#x…

ubuntu22.04安装SecureCRT8.7.3,完成顺利使用

材料准备 scrt-sfx安装包 &#xff0c; securecrt_linux_crack.pl 补丁脚本&#xff0c;和两个依赖库 其中securecrt_linux_crack.pl是找的专门适合 8.7.3版本的&#xff0c;网上很多版本的crack.pl只能打补丁以前的老版本。 而更老版本的SecureCRT对ubuntu22支持更不好&#…

DBeaver导入脚本和导出数据

DBeaver导入脚本和导出数据 前言&#xff1a; 通常产品会要求&#xff0c;把xx表导出Excel&#xff0c;navicat一般公司不让用。讲解使用DBeaver 导入脚本 我们将sql脚本导入DBeaver 1&#xff0c;选择数据库&#xff0c;找到执行脚本 2&#xff0c;选用sql脚本&#xff0…

mavsdk客户端(java)通过mavsdk_server与PX4进行通信

1.启动PX4容器: 2.启动14550与14540监听 3.启动QGC 4.启动mavsdk_server通信中间件 5.启动mavsdk客户端(java) 注:官方示例默认无法连接,修改如下: import io.mavsdk.telemetry.Telemetry;增加设备健康检查才能执行解锁指令Telemetry telemetry = new Telemetry();teleme…

【读书笔】口才三绝

【读书笔记】口才三绝 一、引言二、主要内容概述赞美之绝幽默之绝拒绝之绝 三、个人感悟四、结语我是杰叔叔&#xff0c;一名沪漂的码农&#xff0c;下期再会&#xff01; 一、引言 《口才三绝》是一本专注于提升个人口才与沟通技巧的书籍&#xff0c;它通过丰富的案例和实用的…

macOS Sequoia 15(Macos15系统)v15.0 Beta 3发布 macOS Sequoia 15 功能预览

macOS Sequoia 15 功能预览 犀利一如 Mac macOS Sequoia 15(Macos15系统)v15.0 Beta 3测试版本下载安装 连续互通 你的 Mac 上&#xff0c;iPhone 用起来。 有了 iPhone 镜像功能&#xff0c;在 Mac 上就能看到 iPhone 屏幕画面&#xff0c;还能直接进行操控&#xff0c;不拿…

MySQL存储引擎有哪些?有什么区别?

MySQL存储引擎有哪些&#xff1f;有什么区别 存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式 。存储引擎是基于表的&#xff0c;而不是基于库的&#xff0c;所以存储引擎也可被称为表类型。 在mysql中提供了很多的存储引擎&#xff0c;比较常见有InnoDB、My…

FPGA上板项目(二)——PLL测试

目录 实验内容实验原理实验步骤实验结果 实验内容 将差分时钟信号转化为 192MHz 时钟信号作为输出。 实验原理 PLL&#xff0c;即锁相环&#xff0c;一种反馈控制电路&#xff0c;具有时钟倍频、分频、相位偏移和可编程占空比的功能。 实验步骤 添加 clocking wizard IP核&…