【如何唯一确定一棵二叉树】思想分析及步骤详解

简介: 【如何唯一确定一棵二叉树】思想分析及步骤详解

一、问题引出

二叉树是一种特殊的树,它的每一个结点最多只有左右两棵子树,那么假设我们给定一个二叉树的结点值的遍历结果,如何恢复出树的结构呢?举个最简单的例子,假设给定一个二叉树的前序遍历结果为ABC,现在要根据遍历结果把二叉树恢复出来,那么能得到唯一一棵二叉树吗?显然是不行的,前序遍历是指先访问根结点,再访问左子树,最后访问右子树,那么以下五种情况都符合前序遍历结果ABC。因此,有必要探讨如何唯一确定一棵二叉树。


二、算法介绍

常用的确定一棵二叉树的算法有两种,第一种是使用两种遍历(前序+中序、后序+中序),第二种是#号法。

  • 两种遍历确定一棵二叉树:(必须要有中序遍历)
  • 前序遍历+中序遍历确定一棵二叉树;
  • 中序遍历+后序遍历确定一棵二叉树;
  • #号法确定一棵二叉树:如果没有左右子树,则使用#号代替,遍历时用#代替NULL。

下面分别对两种方法进行详细分析。

1. 中序遍历+前/后序遍历确定一棵二叉树

1.1  算法思想分析

通过上面的介绍可以看到,使用两种遍历来确定一棵二叉树的时候一定要有中序遍历。其实,这和三种遍历的自身特点是有关系的,前序遍历的顺序是先根结点,然后左子树,最后右子树,所以根结点一定在遍历结果的第一个位置上;后序遍历的顺序是,先左子树,然后右子树,最后根结点,所以根结点一定是在遍历结果的最后一个位置上。通过前序遍历和后序遍历可以确定出根结点。中序遍历的顺序是,先左子树,然后根结点,最后右子树,在遍历结果中,左右子树分别在根结点的两侧,这样就可以把左右子树区分开。可以看出,前/后序遍历和中序遍历的作用分别是:

  • 前序遍历或后序遍历用于确定根节点;
  • 中序遍历用于区分左右子树;

通过两种遍历,找出了根结点,并区分开了左右子树,这样就可以确定一棵二叉树了,下面以前序遍历加中序遍历为例,一步步分析如何通过前序遍历结果和中序遍历结果来恢复一棵二叉树(后续+中序遍历的方法与之类似,此文不再分析)。

1.2 算法流程

首先给出两个序列

前序遍历结果:A B C D E F G

中序遍历结果:C D B A F E G

第一步:确定整棵树的根结点及左右子树
  • 根据前序遍历结果确定整棵树的根结点为A ;
  • 根据根结点和中序遍历确定左右子树的结点集合,因为A是整棵树的根结点,中序遍历的顺序是先左子树,然后根结点,最后右子树。所以,在中序遍历结果中,A结点的左侧为左子树结点集合{C, D, B},A结点的右侧为右子树结点集合{F, E, G};

根据分析,可以画出分析后的结果

这样就把问题分解为{C, D, B}和{F, E, G}两个子问题,首先分析左子树

第二步:分析左子树
  • 找出{C, D, B}在前序遍历结果中对应的子序列A (B C D) E F G,将相应子序列拿出来{B C D},根据前序遍历的结果可知,B为这棵子树的根结点;
  • 找出中序遍历中该子树结点集合对应的子序列(C D B) A F E G,根据中序遍历的特点可知,{C D}为根结点B的左子树,B的右子树为空;

继续画出示意图

分析{C,D}子序列

第三步:继续分析左子树的左子树(B结点的左子树)
  • 找出{C, D}在前序遍历结果中对应的子序列A B (C D) E F G,将相应子序列拿出来{C D},根据前序遍历的结果可知,C为这棵子树的根结点;
  • 找出中序遍历中该子树结点集合对应的子序列(C D) B A F E G,根据中序遍历的特点可知,{D}在根结点C的右侧,为根结点C的右子树,C的左子树为空;

继续画出示意图

至此,整棵二叉树的左子树分析完毕,再用第二、三步同样的方法分析右子树{F,E,G}。

第四步:分析右子树
  • 找出{F,E,G}在前序遍历结果中对应的子序列A B C D (E F G),将相应子序列拿出来{F,E,G},根据前序遍历的特点可知,E为这棵子树的根结点;
  • 找出中序遍历中该子树结点集合对应的子序列C D B A (F E G),根据中序遍历的特点可知,{F}为根结点E的左子树,{G}为根结点E的右子树;

画出示意图

整棵二叉树分析完毕,并恢复出唯一的一棵二叉树,我们对该二叉树示意图进行前序遍历和中序遍历,结果分别为A B C D E F G和C D B A F E G,与题目中给的前序遍历序列和中序遍历序列一致,证明我们恢复得到树是正确的。

2. 号法确定一棵二叉树

2.1 算法思想分析

#号法确定一棵树的思想是,如果一个结点没有左右子树,也就是说如果左子树或右子树为NULL,就用一个#号代替,在遍历时给出带有#的遍历结果,既然没有左右子树就用一个#代替,那么连续两个#号前的结点一定是叶子结点,也就能确定一棵子树的结束,这样通过一种遍历的结点序列就能唯一确定一棵二叉树。

2.2 算法流程

首先给出一个#号法前序遍历的结点序列

前序遍历:ABC#D###EF##G##

具体步骤:
  1. 找出后面有连续两个#的结点,D F G这三个结点就是叶子结点;
  2. 根据前序遍历可知,A是整棵树的根结点;
  3. 第一个出现连续两个#的位置为D,所以D结点应该是整棵树的左子树的结束,那么左右子树就区分开了,{B C D}为左子树,{E F G}为右子树;
  4. 分析左子树{B C D}的根结点以及左子树的左右子树。先分理出左子树序列BC#D###,因为是前序遍历,B为左子树的根结点,第一个连续两个#的位置是D,所以D结点是以B为根结点的树的左子树的结束,那么剩下的一个#就是B结点的右子树。因此,B结点的左子树集合为C#D##,B结点的右子树为#;
  5. 分析子树{C#D##},由前序遍历特点可知,C为根结点,D为子树终点,因为D前面有一个#可知,C的左子树为#,右子树为D;
  6. 分析A的右子树{EF##G##},E为根结点,F为左子树,G为右子树;

三、结论

唯一确定一棵树的关键就在于寻找根结点和划分左右子树,不管是前序加中序遍历的方法还是#号法前序遍历的方法,都是在寻找根节点,划分左右子树的一个过程。


相关文章
|
数据采集 XML JSON
获取携程网站上指定景点的用户评论数据
获取携程网站上指定景点的用户评论数据
1158 0
|
数据中心
Zerotier常用命令整理
Zerotier一款可以让您随时随地轻松连接云,移动,桌面和数据中心资源的工具。通过Zerotier可以轻松地将你的多台设备建立局域网,互联互通。本文主要整理Zerotier在日常使用中的命令,以备日常使用查询。
20151 1
Zerotier常用命令整理
|
存储 SQL 数据库
数据库设计案例:电商系统数据库设计实践
数据库设计案例:电商系统数据库设计实践
2453 1
|
JavaScript 数据管理 编译器
揭秘 ArkTS 的五大优势:如何让鸿蒙系统开发更高效、更简单?
【10月更文挑战第18天】ArkTS是专为鸿蒙系统设计的开发语言,结合了TypeScript的类型系统,并在分布式开发、UI开发、性能优化和API支持等方面进行了优化。它提供了一系列专门的API和语法糖,简化多设备协同开发,支持高效能和低功耗,助力开发者充分利用鸿蒙系统的分布式架构和强大功能。
938 5
|
Ubuntu Linux 虚拟化
Linux虚拟机网络配置
【10月更文挑战第25天】在 Linux 虚拟机中,网络配置是实现虚拟机与外部网络通信的关键步骤。本文介绍了四种常见的网络配置方式:桥接模式、NAT 模式、仅主机模式和自定义网络模式,每种模式都详细说明了其原理和配置步骤。通过这些配置,用户可以根据实际需求选择合适的网络模式,确保虚拟机能够顺利地进行网络通信。
1052 1
|
8月前
|
JSON JavaScript 前端开发
gRPC技术中的gRPC到HTTP的转换
从上述内容,我们可以看到,gRPC到HTTP的转换并没有改变gRPC强大的性能和可扩展性。它只是让这些强大的功能能更好地适应不同的环境和需求,兼容了更广泛的网络设施。所以,技术总是在变化,并且始终在寻找更好的平衡点,以满足不断变化的业务需求。我们也应该持续学习,掌握这些新的变化,以便更好地解决实际问题。
247 11
|
11月前
|
Cloud Native 安全 Serverless
Serverless 应用引擎 SAE:让应用管理如此简单
本次课程由阿里云智能集团高级技术专家赵庆杰分享,主题为“Serverless 应用引擎 SAE:让应用管理如此简单”。课程涵盖四个主要部分:降本增效、功能场景、关键技术与客户案例。SAE 引擎通过按量付费、弹性伸缩等特性简化应用管理,帮助企业将更多精力投入到 AI 应用和业务价值上。SAE 提供了低门槛微服务架构转型、应用快速上云、一键启停环境、高可用方案及 CI/CD 解决方案等功能。此外,还介绍了高等教育出版社使用 SAE 进行云原生改造的案例,展示了其在降本增效、提升研发效能和安全性方面的显著成果。
310 9
|
人工智能 数据可视化 Python
【2024美赛】C题 Problem C: Momentum in Tennis网球运动中的势头26页完整论文
本文是关于2024美国大学生数学建模竞赛C题"网球运动中的势头"的完整论文,由一位自称对网球规则和比赛数据非常熟悉的计算机博士撰写,提供了问题分析、数学模型、实现代码和26页的完整论文。
1240 2
【2024美赛】C题 Problem C: Momentum in Tennis网球运动中的势头26页完整论文
|
存储 算法
【博士每天一篇文献-算法】On tiny episodic memories in continual learning
本文研究了在连续学习环境中使用小型情节记忆来解决灾难性遗忘问题,通过实证分析发现经验重播(ER)方法在连续学习中的表现优于现有最先进方法,并且重复训练对过去任务的小型记忆可以提升泛化性能。
175 1
【博士每天一篇文献-算法】On tiny episodic memories in continual learning
|
消息中间件 Java Kafka
Kafka ACK机制详解!
本文深入剖析了Kafka的ACK机制,涵盖其原理、源码分析及应用场景,并探讨了acks=0、acks=1和acks=all三种级别的优缺点。文中还介绍了ISR(同步副本)的工作原理及其维护机制,帮助读者理解如何在性能与可靠性之间找到最佳平衡。适合希望深入了解Kafka消息传递机制的开发者阅读。
1356 0