有4个节点可以构造出 二叉树_【剑指Offer4】图文结合,彻底讲透重建二叉树!...

本文详细介绍了如何通过二叉树的前序遍历和中序遍历结果来重建二叉树。首先,解释了二叉树的先序和中序遍历概念,然后通过手动推导和递归思想,逐步拆分序列并确定每个节点的左右子树。最后,给出了Python代码实现,展示了递归过程中终止条件、返回值和当前递归任务。通过这个过程,读者可以理解重建二叉树的递归算法。
摘要由CSDN通过智能技术生成

v2-2685e8795afe56a67006cce43a07d83c_1440w.jpg?source=172ae18b

题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},请重建二叉树并返回。

解题之前,不妨先回顾一下二叉树的前序(先序)和中序遍历。先序遍历二叉树的操作定义:(1)访问根结点;(2)遍历左子树;(3)遍历右子树,如图1(a)所示。中序遍历二叉树的操作定义:(1)遍历左子树;(2)访问根节点;(3)遍历右子树,如图1(b)所示。

c3f4c7a2922246a3610b72bc13a7405a.png
图 1

利用题目中先序遍历序列和中序遍历序列可手动推导该二叉树模型,推导的中心思想为:1、根据先序遍历序列得到根节点的位置,即首项,因为先序遍历首先遍历二叉树的根节点,2、然后配合中序遍历序列判断根节点的左右子树序列,如图2(a)所示。下面看详细的推导步骤:

步骤一:确定根节点1。根据先序遍历序列得出根节点1,然后配合中序遍历序列得出左右子树,如图2(a)所示,但是此时无法确定左右子树序列中哪项为根结点1的叶结点。我们可以单独考虑根节点1的左右子树,这里我们考虑左子树序列,即图2(a)中红色虚线左侧序列。

9e42d17ecaf162bed161f3f0fa3b9466.png
图 2

步骤二:确定结点2。如图3(a)所示,将根节点1的左子树的前序和中序序列截取出来,利用步骤一的推导方法判断该序列的根节点和左右子树,注意,该中序遍历序列中结点2右边没有项,说明结点2无右子树。

5b02cb6c390b07e228ef9c2a37017807.png
图 3

步骤三:确定结点4。接着把结点2左子树的前序和中序序列截取出来,根据先序遍历序列判断出结点4为结点7的根节点,然后根据中序遍历序列判断出结点7为结点4的右子树。

784044674f325e97767c7a9e60443689.png
图 4

根节点1的右子树推导原理与左子树推导原理一样,大家可以试着推导一下,最终该题的二叉树模型如图5所示。

801e326306ae19ea1754f371679b5a1d.png
图 5

手动推导二叉树模型的过程有助于解题,回顾一下推导过程,是将一个复杂的二叉树序列逐渐分成若干个小的二叉树序列,直到小的二叉树序列能确定自己的左右子树。其实该过程就是一个递归,递归是解决问题的一种方法,其原则是:1、整个递归有终止条件:递归应该在什么时候结束。2、找返回值:应该给上一级返回什么信息。3、本递归应该做什么:在这一级递归中,应该完成什么任务。

这么说好像很抽象,我们以题目为例子,看看怎样使用递归。1、找终止条件:什么情况下递归结束?当然是树为空的时候,此时没有子树序列,递归就结束了。2、找返回值:应该返回什么?从图2(b),3(b)和4(b)可以看出从每一级得到的信息是这一级对应的根节点,因此返回值应该是当前树的根节点。3、本递归应该做什么:在步骤一二三中判断根节点,接着判断左右子树,本题是要重建二叉树,因此在每级递归中,将左右子树连接在根节点上即可。

完整代码如下:

# -*- coding:utf-8 -*-
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        #递归终止条件
        if not pre or not tin:
            return None
        #构造根节点,寻找左右子树的分界线
        root = TreeNode(pre[0])
        n = tin.index(pre[0])
        #构造左右子树,递归调用
        root.left = self.reConstructBinaryTree(pre[1:n + 1], tin[:n])
        root.right = self.reConstructBinaryTree(pre[n + 1:], tin[n + 1:])
        #返回根节点
        return root

参考文献:

1、数据结构(C语言版),严蔚敏,2015

2、Python算法详解,张玲玲,2019

3、Python数据结构与算法分析,布拉德利.米勒,戴维.拉努姆,2019

4、剑指offer python实现 66道算法题,木信,2018

5、剑指面试题重建二叉树,挪罗儿,2020

6、递归三部曲,三年一梦,2019

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值