根据前序遍历序列、中序遍历序列,重建二叉树

本文介绍了如何根据前序遍历和中序遍历序列重建二叉树,详细阐述了重建过程中的关键思路,包括递归处理子树,以及如何确定根节点在中序序列中的位置。同时,提供了代码实现和运行结果,帮助读者理解和掌握这个算法问题。
摘要由CSDN通过智能技术生成

题目

来自剑指Offer的第7题。
在这里插入图片描述

知识储备

要完成这道题,对于二叉树的前序遍历和后序遍历一定要理解到位,下方链接是我之前写的文章,请在做该题目之前阅读完以下文章。
二叉树前序、中序、后序遍历

总体思路

二叉树的前序遍历顺序是:根节点、左子树、右子树,每个子树的遍历顺序同样满足前序遍历顺序。

二叉树的中序遍历顺序是:左子树、根节点、右子树,每个子树的遍历顺序同样满足中序遍历顺序。

前序遍历的第一个节点是根节点,只要找到根节点在中序遍历中的位置,在根节点之前被访问的节点都位于左子树,在根节点之后被访问的节点都位于右子树,由此可知左子树和右子树分别有多少个节点。

由于树中的节点数量与遍历方式无关,通过中序遍历得知左子树和右子树的节点数量之后,可以根据节点数量得到前序遍历中的左子树和右子树的分界,因此可以进一步得到左子树和右子树各自的前序遍历和中序遍历,可以通过递归的方式,重建左子树和右子树,然后重建整个二叉树。

几点思考

思考1:
举个例子:
如果二叉树只有3个节点,前序:1,2,3,中序:2,1,3
前序第一个数为根节点,故根节点为1,在中序里找到根节点1,其左为左子树,右为右子树
故这棵树的形状:根节点1,左子节点2,右子节点3

思考2:
所谓“重建二叉树”,就是创建出各个节点,并让父子节点相连。最后返回整棵树的根节点。

思考3:
序列特点:
前序序列:根节点-左子树的节点们-右子树的节点们(子树的节点们又可以这样分)
中序序列:左子树的节点们-根节点-右子树的节点们(子树的节点们又可以这样分)

思考4:
如何从中序序列数组里找出根节点的位置?
选择使用Map来保存中序序列数组的index和值,来快速进行数组里值的查找
思考:为什么不用Arrays类的binarySearch方法进行二分查找?如果树太大了,多次进行二分查找效率低。

思考5:
递归时,处理的数组是不一样的(树不一样),怎么实现?
一开始处理的数组是给出的两个数组,后来变成数组的子数组,子数组的子数组,即树的子树,子树的子树。
用start、end来指明处理的是数组中的哪一个部分,随着递归而改变。前序序列数组有start、end,后序序列数组也有start、end。

思考6:
递归函数要做什么?
1.更新前序和中序序列的start、end
2.根节点连接左子树,连接右子树
3.返回根节点

代码

先根据2个前序和中序遍历的数组,重建了二叉树。再调用前序遍历方法、中序遍历方法,来遍历此二叉树。观察遍历的顺序是否和给出的两个数组的顺序相同。

import java.util.HashMap;
import java.util.Map;

public class JZO_07 {
   
    /*07. 重建二叉树*/
    /*输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。
    假设输入的前序遍历和中序遍历的结果中都不含重复的数字。*/
    public static void main(String[] args) {
   
        int[] preorder = {
   3,9,20,15,7};
        int[] inorder = {
   9,3
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
拓展前序遍历序列的形式为:[根节点,左子树拓展前序遍历序列,右子树拓展前序遍历序列] 因此,我们可以根据这个拓展前序遍历序列来确定中序遍历序列。 具体步骤如下: 1. 首先,根据拓展前序遍历序列的定义,我们可以得到根节点的值。 2. 接着,根据根节点的值,我们可以将中序遍历序列分为左子树和右子树两部分。 3. 然后,我们可以递归地使用相同的方法来确定左子树的中序遍历序列和右子树的中序遍历序列。 4. 最终,我们将左子树的中序遍历序列和右子树的中序遍历序列按照根节点的位置合并起来,就得到了完整的中序遍历序列。 举个例子,假设我们有以下二叉树: 1 / \ 2 3 / \ 4 5 其拓展前序遍历序列为[1,2,4,null,null,5,null,null,3,null,null],我们可以按照上述步骤来确定中序遍历序列: 1. 根节点为1。 2. 根据根节点的值,中序遍历序列可以分为左子树[4,2,5]和右子树[1,3]两部分。 3. 对于左子树,根节点为2,中序遍历序列可以分为左子树[4]和右子树[2,5]两部分;对于右子树,根节点为3,中序遍历序列可以分为左子树[1]和右子树[]两部分。 4. 将左子树的中序遍历序列[4]和右子树的中序遍历序列[2,5]按照根节点2的位置合并起来得到[4,2,5];将左子树的中序遍历序列[1]和右子树的中序遍历序列[]按照根节点3的位置合并起来得到[1]。最终,将这两个序列合并起来得到完整的中序遍历序列[4,2,5,1,3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值