重建二叉树python,重建二叉树 - 神奇的程序员K的个人空间 - OSCHINA - 中文开源技术交流社区...

前言

给定一颗二叉树的前序遍历和中序遍历的数组,且数组中不包含重复的数字,根据给定的两个数组求出这颗二叉树,这就是重建二叉树问题的定义。

本文将详解重建二叉树问题的解题思路以及其代码实现,欢迎各位感兴趣的开发者阅读本文。

问题描述

我们根据题目的定义来捋一下我们的已知条件以及要解决的问题:

二叉树的前序遍历数组和中序遍历数组

数组中不包含重复数字

根据上述条件重建二叉树

题目分析

乍一看,貌似得不到什么有用的信息,那我们就用一个例子结合题目的已知条件来分析下,看看能不能得到有用的信息。

如下图所示,我们画了一颗二叉树:

3500c924aaf4edc7274de4ef3240ce4f.png

我们来回顾下前序遍历和中序遍历的规则:

前序遍历,先访问根结点,随后访问左子节点,最后访问右子节点

中序遍历,先访问左子节点,随后访问根结点,最后访问右子节点

我们根据上述遍历规则,可得出其两种遍历的元素排列,如下所示:

前序遍历: 8 -> 6 -> 3 -> 7 -> 13 -> 9 -> 15中序遍历: 3 -> 6 -> 7 -> 8 -> 9 -> 13 -> 15

更多有关树的知识可移步我的另一篇文章:TypeScript实现二叉搜索树

我们观察前序遍历和后续遍历的组合后,可得出下述信息:

树根结点的值是8

8位于中序遍历组合的第3号位置

中序遍历组合中,8的左边是它的左子节点,剩余的就是8的右子节点。

前序遍历组合中,8的右边3个元素是它的左子节点,剩余的元素是它的右子节点。

我们发现只要根结点在中序遍历组合的位置,就能确定它的左子节点和右子节点。

实现思路

我们观察树中的每个节点后,发现它们都符合我们上面分析出来的信息,因此我们可以根据树中的每个节点求出它的左子节点和右子节点。

由于树中的每个节点都可以用相同的逻辑求出它的左、右子节点,满足了递归要素,因此我们可以用递归来实现。

更多有关递归的知识,可移步我的另一篇文章:递归的理解与实现

我们来分析下递归的基线条件:

前序遍历和中序遍历的组合其中任意一个为空时,代表它没有子节点了,返回null。

知道基线条件后,我们就可以来实现这个递归函数了。

首先,我们要从前序遍历组合中获取根结点元素

root

随后,根据

root构建一个树节点

tree

求出root在中序遍历组合中的位置

index

递归求出

node的左子节点

递归求出

node的右子节点

最后,

node的左、右子节点都求出来后,将

tree返回,出栈,直至栈内元素被清空,二叉树重建完毕,问题解决。

在递归求node的左、右子节点时,他的前序遍历与中序遍历的组合就是我们之前分析出来的根结点的左右子节点的求法。

我们通过一个例子,来验证下上述思路是否正确,如下所示:

bc63cf9b29b91ad950cbe9e0a7c41971.png

e6d980dfada7c0377146273a181d59c5.png

实现代码

我们有了思路后,接下来接可以用TypeScript将其实现了。

新建一个

TreeOperate.ts文件

声明TreeOperate类

export class TreeOperate {

}

实现重建二叉树函数

buildBinaryTree(prologueArr: T[], middleOrderArr: T[]): Node |null{// 递归基线条件if(prologueArr.length ===0|| middleOrderArr.length ===0) {returnnull;}// 根结点元素constroot = prologueArr[0];// 根据根结点元素构建树节点consttree =newNode(root);// 获取根结点在中序遍历中的位置letindex =0;for(leti =0; i >this.buildBinaryTree(prologueArr.slice(1, index +1), middleOrderArr.slice(0, index));// 递归填充它的右子树,左子树已经填充完成剩余的就是右子树,index+1到它的末尾tree.right = >this.buildBinaryTree(prologueArr.slice(index +1), middleOrderArr.slice(index +1));// 返回tree,出栈,直至栈内元素被清空,二叉树重建完毕,问题解决。returntree;}

上述代码地址:TreeOperate.ts

编写测试代码

我们将上图中的例子放进代码中验证下我们实现的函数是否正确执行。

import { TreeOperate } from "./lib/TreeOperate.ts";

const treeOperate = new TreeOperate();

const result6 = treeOperate.buildBinaryTree([8, 6, 3, 7, 13, 9, 15], [3, 6, 7, 8, 9, 13, 15]);

console.log(result6);

eb683035a9b08e65c3bece5988840359.png

写在最后

公众号无法外链,文中链接可点下方阅读原文进行查看。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值