问题描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
算法
1、根据前序遍历序列第一个节点确定根节点(root)
2、根据根节点在中序序列中的位置分割出左右两个子序列
3、对左子树和右子树分别递归使用同样的方法继续分解
分析
切割1的左右子树
分析1的左子树
分析1的右子树
合成分析左右子树
代码
package ATree;
import java.util.Arrays;
/**
* @Author Zhou jian
* @Date 2020 ${month} 2020/3/13 0013 14:15
*
* 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
* 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
* 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},
* 则重建二叉树并返回。
*/
public class Problem1 {
public TreeNode reConstructBinaryTree1(int [] pre,int [] in) {
//健壮性检查
if(pre.length == 0||in.length == 0){
return null;
}
//在前序遍历中先找到根节点
TreeNode node = new TreeNode(pre[0]);
//在中序遍历中找到前序的根
//这样就可以确定左子树的前序和左子树的中序
// 右子树的前序和右子树的中序
//不断递归 对左子树进行重建,对右子树进行重建
//
for(int i = 0; i < in.length; i++){
if(pre[0] == in[i]){
//左子树,注意copuOfRange函数,左闭右开
node.left = reConstructBinaryTree1(Arrays.copyOfRange(pre, 1, i+1), Arrays.copyOfRange(in, 0, i));
//右子树,注意copuOfRange函数,左闭右开
node.right = reConstructBinaryTree1(Arrays.copyOfRange(pre, i+1, pre.length), Arrays.copyOfRange(in, i+1,in.length));
}
}
return node;
}
public static void main(String[] args) {
int[] prev = {1,2,4,7,3,5,6,8};
int[] in = {4,7,2,1,5,3,8,6};
Problem1 problem1=new Problem1();
TreeNode head= problem1.reConstructBinaryTree1( prev, in);
//前序遍历
head.preOrder();
System.out.println();
//中序遍历
head.middleOrder();
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
//前序遍历
public void preOrder(){
System.out.print(this.val+" ");
if(this.left!=null){
this.left.preOrder();
}
if(this.right!=null){
this.right.preOrder();
}
}
//中序遍历
public void middleOrder(){
if(this.left!=null){
this.left.middleOrder();
}
System.out.print(this.val+" ");
if(this.right!=null){
this.right.middleOrder();
}
}
}