重建二叉树-牛客网-剑指offer

1.问题描述

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

2.问题分析

  2.1首先了解二叉树的结构

     2.2了解二叉树的三种遍历顺序(前序遍历,中序遍历和后序遍历)

    前序遍历:中左右

           中序遍历

           后序遍历

  根据前序遍历序列和中序遍历序列,或后序遍历序列和中序遍历序列,能唯一确定二叉树。

  2.3迭代的编程思想

 

3.源代码

package www.nowcoder.com.conquerOffer.binaryTree;

import java.util.Arrays;

/**
 * 重建二叉树
 * 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。 
 * http://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
 * @author sunny
 *
 */
public class BinaryTreeRebuild {
    /**
     * 重建二叉树 
     * @param pre 前序遍历序列数组
     * @param in 中序遍历序列数组
     * @return 二叉树根节点
     */
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        //第一步:校验前序遍历序列或中序遍历序列数组是否为空
        if(null == pre || null == in || pre.length <= 0 || in.length <= 0)
            return null;
        //第二步:从前序遍历序列中获取根节点的值
        int rootVal = pre[0];    
        //第三步:设置根节点的值
        TreeNode rootNode = new TreeNode(rootVal);
        //第四步:获取根节点在中序遍历序列中的索引值
        int rootIndex = findInArray(in, rootVal);    //数组工具类自带的二分查找算法
        //第五步:获取左子树的前序遍历序列、右子树的前序遍历序列,左子树的中序遍历序列、右子树的中序遍历序列
        //左子树的前序遍历序列
        int[] preLeft = Arrays.copyOfRange(pre, 1, rootIndex+1);
        //右子树的前序遍历序列
        int[] preRight = Arrays.copyOfRange(pre, rootIndex+1, pre.length);
        //左子树的中序遍历序列
        int[] inLeft = Arrays.copyOfRange(in, 0, rootIndex);
        //右子树的中序遍历序列
        int[] inRight = Arrays.copyOfRange(in, rootIndex+1, pre.length);
        BinaryTreeRebuild binaryTreeRebuild = new BinaryTreeRebuild();
        //第六步:构建左子树和右子树
        TreeNode leftTree = binaryTreeRebuild.reConstructBinaryTree(preLeft, inLeft);
        TreeNode rightTree = binaryTreeRebuild.reConstructBinaryTree(preRight, inRight);
        //第七步:设置根节点的左子树和右子树
        rootNode.setLeft(leftTree);
        rootNode.setRight(rightTree);
        return rootNode;
    }
    
    /**
     * 获取数组中目标的下标
     * @param arr 数组
     * @param target 查找的目标 
     * @return
     */
    private static int findInArray(int[] arr, int target) {
        //数组为空
        if(null == arr || arr.length <= 0)
            return -1;
        for(int i = 0; i < arr.length; i++){
            if(target == arr[i])
                return i;
        }
        return -1;
    }

    public static void main(String[] args) {
        //前序遍历序列
        int[] pre = new int[]{1,2,4,7,3,5,6,8};
        //中序遍历序列
        int[] in = new int[]{4,7,2,1,5,3,8,6};
        BinaryTreeRebuild binaryTreeRebuild = new BinaryTreeRebuild();
        TreeNode rootNode = binaryTreeRebuild.reConstructBinaryTree(pre, in);
        System.out.println(rootNode);
    }

}

/**
 * 二叉树节点
 * @author sunny
 *
 */
class TreeNode {
    int val;    //节点值
    TreeNode left;    //左子树
    TreeNode right;    //右子树
    TreeNode(int x) { val = x; }    //构造函数
    //左子树的set方法
    public void setLeft(TreeNode left) {
        this.left = left;
    }
    //右子树的set方法
    public void setRight(TreeNode right) {
        this.right = right;
    }
}

4.运行效果

1 www.nowcoder.com.conquerOffer.binaryTree.TreeNode@28d76d1e
运行效果

 

posted on 2015-10-20 10:33  巧天工  阅读(410)  评论(0编辑  收藏  举报

导航