热门标签 | 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




推荐阅读
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 本文讨论了在Spring 3.1中,数据源未能自动连接到@Configuration类的错误原因,并提供了解决方法。作者发现了错误的原因,并在代码中手动定义了PersistenceAnnotationBeanPostProcessor。作者删除了该定义后,问题得到解决。此外,作者还指出了默认的PersistenceAnnotationBeanPostProcessor的注册方式,并提供了自定义该bean定义的方法。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • modulepaddle.fluidhasnoattributedata解决:pipinstallpaddlepaddle-gpu1.7.0.post107-ih ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
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社区 版权所有