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

本文介绍了如何根据前序遍历和中序遍历序列重建二叉树,详细阐述了重建过程中的关键思路,包括递归处理子树,以及如何确定根节点在中序序列中的位置。同时,提供了代码实现和运行结果,帮助读者理解和掌握这个算法问题。
摘要由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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值