首页 > 技术文章 > 面试题3(剑指)-重建二叉树

limaosheng 2019-02-21 17:44 原文

题目

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

利用递归的方法构建,其实没有想象的那么难,主要是理解构建过程就行!!

思想构建过程

题目中前序遍历的第一个节点{1}一定是这棵二叉树的根节点,根据中序遍历序列,可以发现中序遍历序列中节点{1}之前的{4,7,2}是这棵二叉树的左子树,{5,3,8,6}是这棵二叉树的右子树。然后,对于左子树,递归地把前序子序列{2,4,7}和中序子序列{4,7,2}看成新的前序遍历和中序遍历序列。此时,对于这两个序列,该子树的根节点是{2},该子树的左子树为{4,7}、右子树为空,如此递归下去(即把当前子树当做树,又根据上述步骤分析)。{5,3,8,6}这棵右子树的分析也是这样。

实现

二叉树结点  BinaryTreeNode

//二叉树节点
public class BinaryTreeNode {
    public int data;
    public BinaryTreeNode left;
    public BinaryTreeNode right;

    public BinaryTreeNode(int data, BinaryTreeNode left, BinaryTreeNode right){
        super();
        this.data = data;
        this.left = left;
        this.right = right;
    }

    public BinaryTreeNode(int data){
        this.data = data;
    }
}

构建

package lms.datastructure.tree;

import java.util.Arrays;

public class ConstructTree {
    public static BinaryTreeNode reConstruct(int[] preOrder, int[] inOrder) {

        if (preOrder == null || inOrder == null) {
            return null;
        }

        //从先序遍历中取出根节点,构造二叉树
        int rootData = preOrder[0];
        BinaryTreeNode root = new BinaryTreeNode(rootData);
        root.left = root.right = null;

        //只有一个数字情况 也是递归的终止条件
        if (preOrder.length == 1 && inOrder.length == 1) {
            if (inOrder[0] == preOrder[0]) {
                return root;
            } else {
                throw new IllegalArgumentException("invalid input");
            }
        }

        //中序中找到
        int rootinIndex = 0;
        while (rootinIndex < inOrder.length && rootData != inOrder[rootinIndex]) {
            rootinIndex++;
        }

        //同样的方法递归左右子树
        //中序中位置判断是否有左子树
        if (rootinIndex > 0) {
            root.left = reConstruct(
                    Arrays.copyOfRange(preOrder, 1, rootinIndex + 1),
                    Arrays.copyOfRange(inOrder, 0, rootinIndex));
        }
        //判断结点有右子树
        if (rootinIndex < inOrder.length - 1) {
            root.right = reConstruct(
                    Arrays.copyOfRange(preOrder, rootinIndex + 1, preOrder.length),
                    Arrays.copyOfRange(inOrder, rootinIndex + 1, inOrder.length)
            );
        }

        //返回构造的根结点
        return root;
    }

    //=====后序遍历============
    //递归 后序
    public static void postOrderRecur(BinaryTreeNode root) {
        if (null != root) {
            postOrderRecur(root.left);
            postOrderRecur(root.right);
            System.out.print(root.data + " ");
        }
    }

    public static void main(String[] args) {

        /**
         *             1
         *           /   \
         *          2     3
         *         /     / \
         *        4     5   6
         *         \       /
         *         7      8
         */

        int[] pre = {1, 2, 4, 7, 3, 5, 6, 8};
        int[] in = {4, 7, 2, 1, 5, 3, 8, 6};

        BinaryTreeNode root = reConstruct(pre, in);

//后序遍历构造后的二叉树
postOrderRecur(root);
    }
}

 

输出结果

7 4 2 5 8 6 3 1 

 

结果为后序遍历结果

 

推荐阅读