【剑指offer】【4】根据前序和中序结果,重建二叉树

题目:

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


1、分析原理:

        根据前序和中序的特性,前序序列的一个元素就是树的根元素,那么在中序序列找到相应的元素。找到后该元素前面所有元素都是左子树元素,后面元素都是右子树元素。那么此时跟节点的pleft就是左子树返回的结果,pright就是右子树返回的结果,使之递归即可,递归出口就是前序区间只有一个元素时。 

这里写图片描述
2、思路一:前序和中序必须结合搭配
使用递归,每次分清根结点、左子树、右子树,递归进行构建。

先序遍历第一个位置肯定是根节点node,中序遍历的根节点位置在中间p,在p左边的肯定是node的左子树的中序数组,p右边的肯定是node的右子树的中序数组。

重构函数(前序数组,前序数组头,前序数组尾,中序数组,中序数组头,中序数组尾);

根据前序数组的第一个值遍历中序数组,找到之后即可分清前序和中序数组中左子树和右子树的组成部分,得到四个新的数组。
新左子树:前序部分、中序部分
新右子树:前序部分、中序部分

注意:数组的边界

找到左右子树之后,当成新的前序中序数组传入重构函数进进一步构建,递归! 


/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;  //左子树
 *     TreeNode right; //右子树
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {  //输入前序中序数组
        return reConBTree(pre,0,pre.length-1,in,0,in.length-1);
    }
    //使用递归不断寻找根节点、左子树、右子树
    //每次都输入新的树的前序和后序数组
    public TreeNode reConBTree(int[] pre, int preleft, int preright, int[] in, int inleft, int inright){
        if(preleft > preright || inleft > inright){  //数组遍历完毕
            return null;
        }
        //新建一个TreeBTree
        TreeNode root = new TreeNode(pre[preleft]);
        //遍历中序数组,找到根节点,和左右子树
        for(int i=0; i < in.length; i++){
            if(in[i] == pre[preleft]){
                //重构左子树,使用递归
                root.left = reConBTree(pre, preleft+1, preleft+i-inleft, in, inleft, i-1);
                //重构右子树,使用递归
                root.right = reConBTree(pre, preleft+i-inleft+1, preright, in, i+1, inright);
            }
        }
        return root;
    }
}

猜你喜欢

转载自blog.csdn.net/love_aym/article/details/80602335