热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c++二叉树_大牛带你学|由二叉树的遍历序列求二叉树结构的解题方法归纳

前言二叉树章节属于数据结构考察的三大重点章节(线性表、树、图)之一,不管是在自命题院校考察和408统考都是考察频次很高的考点。今天,大牛学长就来为各位同

305852e2b05e2ee4fad1c95e4cb0f638.png

前言

二叉树章节 属于数据结构考察的三大重点章节(线性表、树、图)之一,不管是在自命题院校考察和408统考都是考察频次很高的考点。今天,大牛学长就来为各位同学总结归纳一个二叉树知识考察中的常见题型的解题方法。

在二叉树相关考察中,有这样一类题型,它形如【已知二叉树的中序遍历序列和先序遍历序列,求二叉树的后序遍历序列】同时,这类题很容易在选择题中衍生成其他题型,因此掌握它的固定解法是相当重要的。由于在解得二叉树的形态后求相关遍历序列非常简单,我们把这一类问题归结为:【由二叉树的遍历序列求二叉树结构】。

c73c5488d15898de215cb6ba6e9d27e7.png预备知识

要解决这一类问题,我们需要先回顾一下二叉树的结构以及它的四种遍历方式的特点。我们知道任何二叉树可以分为三部分:根结点(D)、左子树(L)、右子树(R)。所谓遍历二叉树,就是按某种顺序访问这三个部分。根据不同顺序可以把遍历方法分层三类:

DLR——先(根)序遍历。

LDR——中(根)序遍历。

LRD——后(根)序遍历。

同时我们也可以按层次观察:

从根结点开始遍历,按层次次序, “自上而下,从左至右”访问树中的各结点。

6df0733140e4e50e838b0cac35d4cacf.png

先序遍历ABDEC

中序遍历DBEAC

后序遍历DEBCA

层序遍历ABCDE

由此我们得到了四种遍历方式:先序遍历、中序遍历、后序遍历、层序遍历。

根据大牛学长画出的示意图,我们一起观察一下四种遍历方式的特点:

对于根结点A来说,左子树对应的是BDE这三个结点,右子树对应的是C这个结点。

• 先序遍历:DLR,以A为根结点的先序遍历序列是ABDEC,以B为根结点的先序遍历序列是BDE,以C为根结点的先序遍历序列是C。显然在先序遍历的序列当中,我们可以根据DLR划分为三个部分 (A)(BDE)(C),并且每一个部分都符合先序遍历。

• 后序遍历:LRD,以A为根结点的后序遍历序列是DEBCA,以B为根结点的后序遍历序列是DEB,以C为根结点的后序遍历序列是C。显然在后序遍历的序列当中,我们可以根据LRD划分为三个部分 (DEB)(C)(A),并且每一个部分都符合后序遍历。

• 中序遍历:LDR,以A为根结点的中序遍历序列是DBEAC,以B为根结点的中序遍历序列是DBE,以C为根结点的中序遍历序列是C。显然在中序遍历的序列当中,我们可以根据DLR划分为三个部分(DBE)(A)(C),并且每一个部分都符合中序遍历。

• 层序遍历:以A为根结点的中序遍历序列是ABCDE,以B为根结点的中序遍历序列是BDE,以C为根结点的中序遍历序列是C。层序遍历的分析比较复杂,但是我们可以根据已知的树结点的情况对遍历序列进行划分,划分为(A)(BCDE)两部分。显然层序遍历的第二部分当中左子树和右子树的结点是交替输出的,不像前三种遍历左子树和右子树独立输出,但是我们可以根据已知左子树对应的是BDE这三个结点,在遍历序列ABCDE当中选取BDE三个结点保留他们的相对位置,得到的(BDE)对应的正是左子树的层次遍历,同样的根据右子树对应的是C这个结点,在遍历序列中选取的(C)对应的正是右子树的层次遍历。

c73c5488d15898de215cb6ba6e9d27e7.png大牛总结

对于先序遍历、后序遍历以及层序遍历来说,都能够唯一地确定根结点的值!这一点异常重要!

先序遍历和层序遍历中根结点总是在序列的 第一位,

后序遍历中根结点总是在序列的 最后一位。

对于中序遍历来说,如果能够唯一地确定根结点的值,设根结点所在下标为i,那么[0...i-1]对应的就是左子树的中序遍历序列,[i+1...n]对应的就是右子树的中序遍历序列。

由此我们可以确定左子树拥有哪些结点,以及右子树拥有哪些结点。

通过遍历确定唯一的二叉树

要知道,通过遍历序列确定二叉树形态这样的操作虽然很常见,但是,存在不能确定形态的情况!

(一)单一的遍历序列不能够确定唯一一个二叉树

(二)四种遍历序列中,任意取其两种,也不一定能够确定二叉树具体确定情况如下表所示。可以看出,确定二叉树的规则可以总结为:

中序遍历是必须!其余三种取其一。

任何不满足这个口诀的序列方法都是不能唯一确定二叉树的!

fd568101e9332d2b9db4471f402c63e3.png

对于为什么不能通过先序遍历、后序遍历、层序遍历三者中的任意组合唯一确定二叉树,可以参考上面的分析过程,也可以记住一个这样的反例。这两个不相同的二叉树拥有相同的先序遍历、后序遍历、层序遍历序列。

143976fe2891ecb57a78a1e5091a7799.png

前面提到了通过先序遍历、后序遍历以及层序遍历能够唯一地确定根结点的值。当我们通过以上的三种序列之一拿到根节点值之后,观察中序遍历序列可以确定左子树和右子树拥有的结点情况。

若能确定先序遍历、后序遍历哪些结点属于左子树或右子树,对应的左子树和右子树的先序遍历、后序遍历又能唯一地确定其根结点的值。

这时候,将子树当成一棵新的树,重新去重复“找根节点、划分左右子树”的流程,直到找到所有叶子节点,二叉树的形态确定过程基本也就完成了。

c73c5488d15898de215cb6ba6e9d27e7.png常见题型

在整理好逻辑之后,大牛学长来跟大家归纳常考的题型。

具体试卷上,一般考察知道中序遍历序列,以及先后序遍历序列之一的二叉树确定问题(结点数量为n,序列下标从0开始)。根据前面的逻辑整理,这种情况的解题步骤可以归纳为:

(1)在先序遍历(后序遍历)中选择 第一个(最后一个)作为根结点T

(2)在中序遍历中寻找T,确定下标为i,则左子树为inorder[0...i-1]长度为i,右子树为inorder[i+1...n-1]长度为n-i-1

(3)在先序遍历(后序遍历)中以preorder[1...i](postorder[0...i-1])为左子树,对左子树执行(1),以preorder[i+1...n-1](postorder[i...n-2])为右子树,对右子树执行(1)

而对于已知层序遍历和中序遍历(结点数量为n,序列下标从0开始

)唯一确定二叉树基本的解题步骤为:

(1)在层序遍历中选择 第一个(最后一个)作为根结点T

(2)在中序遍历中寻找T,确定下标为i,则左子树为inorder[0...i-1]长度为i,右子树为inorder[i+1...n-1]长度为n-i-1

(3)在层序遍历中按照inorder[0...i-1]遍历整个levelorder序列确定i个结点为左子树,对左子树执行(1),按照inorder[i+1...n-1]确定n-i-1个结点为右子树,对右子树执行(1)

c73c5488d15898de215cb6ba6e9d27e7.png解题实战

题目:若某一二叉树的先序遍历序列为ABDEC,其中序遍历序列为DBEAC,求该二叉树的形态(恢复该二叉树)。

解答:

(1) 由于知道了该二叉树的先序遍历序列,可知其根节点为A。

(2) 将A拿到中序遍历序列中,可以看到A把二叉树分成了两部分,左子树DBE,右子树C。

(3) 对于整个二叉树来说,根节点A和A的唯一右子树(一个节点)C已经确定,接下来需要确定其右子树DBE(中序序列)了。

(4) A的左子树的先序遍历序列是BDE,因此很明确的知道B是左子树的根节点,也就是A的左儿子,于是把B节点拿到中序序列DBE中,看出B刚好把D、E分开,于是可以得到左子树是以B为根节点,D、E分别为左右子树的二叉树,将该二叉树放到A的左子树位置即可。最终树的形态如下图所示。

6df0733140e4e50e838b0cac35d4cacf.png

好啦,对于如何从两种二叉树遍历序列中求出二叉树形态类型题的总结和归纳就到此为止啦!希望同学们能够从中得到提升哟~

大牛学长也会不断发掘考点考题,为大家带来更加丰富有用的知识、题型总结!

今天是2020年8月14日

距离2021年考研还有 126 天  

乾坤未定,你我皆是黑马。

大牛学长一直在~

3a9b9d18a57f6c5a895feb4b29caacc8.png




推荐阅读
  • 在CodeIgniter框架中集成新库文件的过程中,我遇到了一些困惑。具体来说,在跟随nettuts的认证教程时,对于在Welcome控制器中添加的构造函数代码,特别是关于Session的验证部分,我感到不太理解。这部分内容涉及如何确保Session已经初始化并具备相应的功能,这对于实现用户认证至关重要。为了更好地掌握这一知识点,我计划深入研究CodeIgniter的官方文档,并参考更多相关资源,以确保能够正确地集成和使用新库文件。 ... [详细]
  • 在ASP.NET中,实现页面间数据传递有多种技术方案。其中一种常见方法是通过URL链接地址传递参数,例如在 `send.aspx` 页面中,可以通过点击按钮将数据附加到URL中,然后在目标页面 `receive.aspx` 中解析这些参数。此外,还可以利用Session、ViewState、Cookie等机制来实现跨页面的数据共享,每种方法都有其适用场景和优缺点。 ... [详细]
  • 掌握Android UI设计:利用ZoomControls实现图片缩放功能
    本文介绍了如何在Android应用中通过使用ZoomControls组件来实现图片的缩放功能。ZoomControls提供了一种简单且直观的方式,让用户可以通过点击放大和缩小按钮来调整图片的显示大小。文章详细讲解了ZoomControls的基本用法、布局设置以及与ImageView的结合使用方法,适合初学者快速掌握Android UI设计中的这一重要功能。 ... [详细]
  • 开发日志:在插入数据到一张表的同时更新另一张表的技术细节与最佳实践 ... [详细]
  • 利用CSV Data Set Config实现JMeter参数化测试的详细指南
    本文详细介绍了如何使用JMeter中的CSV Data Set Config元素来实现参数化测试。通过该配置元件,用户可以轻松地从外部CSV文件中读取数据,从而提高测试的灵活性和可扩展性。文章不仅提供了具体的配置步骤,还结合实际案例,展示了如何在不同的测试场景中应用这一功能,帮助读者更好地理解和掌握JMeter参数化测试的技巧。 ... [详细]
  • 在过去,我曾使用过自建MySQL服务器中的MyISAM和InnoDB存储引擎(也曾尝试过Memory引擎)。今年初,我开始转向阿里云的关系型数据库服务,并深入研究了其高效的压缩存储引擎TokuDB。TokuDB在数据压缩和处理大规模数据集方面表现出色,显著提升了存储效率和查询性能。通过实际应用,我发现TokuDB不仅能够有效减少存储成本,还能显著提高数据处理速度,特别适用于高并发和大数据量的场景。 ... [详细]
  • 通过使用Wireshark对POP3和SMTP协议进行详细的抓包与分析,本实验旨在帮助读者初步掌握Wireshark的使用技巧,熟悉其抓包流程,并通过实际案例深入理解这两种电子邮件协议的工作机制。此外,实验还将探讨如何利用Wireshark识别和解析协议数据包中的关键信息,为网络故障排除和安全审计提供有力支持。 ... [详细]
  • Sanic 是一个类似于 Flask 的 Python 3.5 Web 服务器,以其出色的写入速度而著称。与 Flask 不同,Sanic 支持异步请求处理,这使得它在处理高并发请求时表现更加出色。通过利用 Python 的异步特性,Sanic 能够显著提高应用程序的性能和响应能力,适用于构建高性能的异步 Web 应用。 ... [详细]
  • 深入解析 Vue 中的 Axios 请求库
    本文深入探讨了 Vue 中的 Axios 请求库,详细解析了其核心功能与使用方法。Axios 是一个基于 Promise 的 HTTP 客户端,支持浏览器和 Node.js 环境。文章首先介绍了 Axios 的基本概念,随后通过具体示例展示了如何在 Vue 项目中集成和使用 Axios 进行数据请求。无论你是初学者还是有经验的开发者,本文都能为你解决 Vue.js 相关问题提供有价值的参考。 ... [详细]
  • 在PHP的设计中,预定义了9个超级全局变量、8个魔术变量和13个魔术函数,这些变量和函数无需声明即可在脚本的任意位置使用。这些特性在PHP开发中极为常见,能够显著提升开发效率和代码的灵活性。相比之下,Java并没有类似的内置机制,但通过其他方式如上下文对象和反射机制,也可以实现类似的功能。本文将详细探讨这两种语言中这些特殊变量和函数的使用方法及其应用场景。 ... [详细]
  • 揭秘腾讯云CynosDB计算层设计优化背后的不为人知的故事与技术细节
    揭秘腾讯云CynosDB计算层设计优化背后的不为人知的故事与技术细节 ... [详细]
  • 在Bugku Web CTF实战演练中,通过细致的源代码检查,我们发现了一个隐藏的滑稽笑脸图标,进一步分析后成功找到了flag。此外,还探讨了如何利用计算器功能进行安全测试,提升了对Web漏洞的识别和利用技巧。 ... [详细]
  • 在数据表中,我需要触发一个操作来刷新特定列的数据。例如,对于以下表格:| ID | Name | IsDeleted ||----|-------|-----------|| 1 | test | True || 2 | test2 | False |我希望在点击“更新”按钮时,能够仅刷新选定行的“IsDeleted”列。这将有助于确保数据的实时性和准确性。 ... [详细]
  • 在Formtastic中,预选模型对象集合作为复选框的使用方法与技巧。本文介绍了如何将模型对象集合传递给Formtastic表单,并在复选框中预选这些对象。通过示例代码和详细解释,展示了如何高效地实现这一功能,确保用户界面友好且操作简便。具体来说,通过 `@things = Thing.all` 将所有对象加载到集合中,并在表单中进行预选。这种方法不仅提高了代码的可读性和维护性,还增强了用户体验。 ... [详细]
  • React 实现 Post 请求下载 PDF 文件的解决方案
    在 React 应用中实现通过 POST 请求下载 PDF 文件的功能,本文提供了完整的代码示例。具体实现包括设置状态以显示加载提示,并通过控制台日志记录下载索引,确保请求的正确性和用户体验。此外,还详细介绍了如何处理响应流并将其转换为可下载的 PDF 文件,适用于需要安全传输数据的场景。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有