题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
分析过程
利用前序序列根节点在前找到根节点,用根节点去中序序列划分成两部分,
左部分是左子树,右部分是右子树。
再利用子树长度去前序序列把前序序列中的左右子树找出来,
同时可以找出根节点。
递归进行此步骤,如果子树长度为0,则不需要生成子问题。
到最后左子树或者右子树为null时,则那条语句执行完
整个treeNode的根及左右子节点全被赋予值,最后为null

  • */
    import java.util.Arrays;

public class Offer4BinaryTree {
public static 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]) {
        //左子树,注意copyOfRange函数,左闭右开
        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));
        //右子树
        //根据中序遍历,知道左子树有多少个节点,因而在前序遍历的数组中对应的左子树也应该有多少个,并且是从下标1开始
        //左子树的开头是第二个数,中间包含节点的数量为中序从0到根节点的数量
        //所以是pre[1:pre.index(pre[0])+1]
        //break;
    }
}


return root;
}

public static void printBinaryTree(TreeNode res) {
while (res.left!=null||res.right!=null) {
System.out.print(res.val+" ");
//print打印二叉树

}

}

public static void main(String[] args) {
    int[]pre= {1,2,4,7,3,5,6,8};
    int []mid={4,7,2,1,5,3,8,6};
    TreeNode res=reConstructBinaryTree(pre,mid);
    reConstructBinaryTree(pre,mid);
}

}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}

递归构建二叉树

  1. 分析
    根据中序遍历和前序遍历可以确定二叉树,具体过程为:

根据前序序列第一个结点确定根结点
根据根结点在中序序列中的位置分割出左右两个子序列
对左子树和右子树分别递归使用同样的方法继续分解

例如:
前序序列{1,2,4,7,3,5,6,8} = pre
中序序列{4,7,2,1,5,3,8,6} = in

根据当前前序序列的第一个结点确定根结点,为 1
找到 1 在中序遍历序列中的位置,为 in[3]
切割左右子树,则 in[3] 前面的为左子树, in[3] 后面的为右子树
则切割后的左子树前序序列为:{2,4,7},切割后的左子树中序序列为:{4,7,2};切割后的右子树前序序列为:{3,5,6,8},切割后的右子树中序序列为:{5,3,8,6}
对子树分别使用同样的方法分解,递归进行此步骤,如果子树长度为0,则不需要生成子问题。

  • */