题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
解题思路
- 已知前序遍历序列和中序遍历序列,可以唯一确定一棵二叉树。
- 已知后序遍历序列和中序遍历序列,可以唯一确定一棵二叉树。
- 但是已知前序遍历序列和后序遍历序列,是不能确定一棵二叉树的。
下面例子通过前序遍历
和中序遍历
确定唯一的一棵二叉树。
前序遍历:[1,2,4,7,3,5,6,8]
中序遍历:[4,7,2,1,5,3,8,6]
1、首先根据前序遍历
找出根节点是1,然后根据中序遍历
可以知道472是1的左子树,5386是1的右子树。
前序遍历:[1,2,4,7,3,5,6,8]
中序遍历:[4,7,2,1,5,3,8,6]
2、然后根据左子树的先序:247,中序:472,确定2为根结点,左子树为47,无右子树
前序遍历:[1,2,4,7,3,5,6,8]
中序遍历:[4,7,2,1,5,3,8,6]
3、右子树为47,先序:47,中序:47,确定4为根结点,无左子树,右子树为7
前序遍历:[1,2,4,7,3,5,6,8]
中序遍历:[4,7,2,1,5,3,8,6]
4、右子树为5386,先序:3568,中序:5386,确定3为根结点,左子树为5,右子树为86
前序遍历:[1,2,4,7,3,5,6,8]
中序遍历:[4,7,2,1,5,3,8,6]
5、右子树为86,先序:68,中序:86,确定6为根结点,左子树为8,无右子树。
6、最终的二叉树为:
前序遍历:[1,2,4,7,3,5,6,8]
中序遍历:[4,7,2,1,5,3,8,6]
后序遍历为:7,4,2,5,8,6,3,1
后序遍历序列和中序遍历序列,可以唯一确定一棵二叉树和前中很相似,先根据后序遍历的最后一个元素确定根结点,然后通过中序遍历分为左右子树,再在子树确定根结点,以此类推。
解题思路:
- 首先根据根节点a将中序遍历划分为两部分,左边为左子树,右边为右子树
- 在左子树中根据第一条规则递归,得出左子树
- 在右子树中根据第一条规则递归,得出右子树
- 最后合成一棵树
java代码
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
import java.util.Arrays;
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre.length==0 || in.length==0){
return null;
}
TreeNode root = new TreeNode(pre[0]);
for(int i=0;i<in.length;i++){
if(in[i]==pre[0]){
// 左子树
root.left = reConstructBinaryTree(Arrays.copyOfRange(pre,1,i+1),Arrays.copyOfRange(in,0,i));
// 右子树
root.right = reConstructBinaryTree(Arrays.copyOfRange(pre,i+1,pre.length),Arrays.copyOfRange(in,i+1,in.length));
}
}
return root;
}
}
python 代码:
# -*- coding:utf-8 -*-
class TreeNode:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
# write code here
if len(pre) == 0 or len(tin) == 0:
return None
root = pre[0] # 根节点
flag = tin.index(pre[0]) # 找到根节点在中序遍历中的索引
n = TreeNode(root) # 创建二叉树
# 左子树的先序和中序遍历
n.left = self.reConstructBinaryTree(pre[1:1 + flag], tin[:flag])
# 右子树的先序和中序遍历
n.right = self.reConstructBinaryTree(pre[flag + 1:], tin[flag + 1:])
return n
if __name__ == '__main__':
pre_order = [1, 2, 4, 7, 3, 5, 6, 8, 9]
mid_order = [4, 7, 2, 1, 5, 3, 8, 6, 9]
s = Solution()
root = s.reConstructBinaryTree(pre_order, mid_order)