Java 剑指offer 面试题7:重建二叉树

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/weixin_43014205/article/details/85945094

给出二叉树的中序和前序遍历,重建该二叉树,或者给出中序和后序遍历,重建二叉树。

思路:

对于无论是前序+中序重建二叉树,还是后序+中序

中序都是来提供左右子树的划分,而前序和后序是来判断根节点

先定义树的结构体

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

根据中序+前序重构二叉树代码:

import java.util.Arrays;

public class reConBinaryTreeByPreAndIn {
    public static TreeNode conBinaryTree(int[] pre,int[] in){
        if(pre==null||in==null){
            return null;
        }
        if(pre.length==0||in.length==0){
            return null;
        }
        if(pre.length!=in.length){
            return null;
        }
        //根据先序,可以直接确定根的值
        TreeNode root = new TreeNode(pre[0]);
        for(int i=0;i<in.length;i++){
            if(root.val==in[i]){
                root.left=conBinaryTree(Arrays.copyOfRange(pre,1,i+1),Arrays.copyOfRange(in,0,i));
                root.right=conBinaryTree(Arrays.copyOfRange(pre,i+1,pre.length),Arrays.copyOfRange(in,i+1,in.length));
            }
        }
        //判断后没有左子树也没有右子树,返回根节点root
        return root;
    }

    //后序遍历打印二叉树
    public static void postPrint(TreeNode head){
        if(head == null){
            return;
        }
        postPrint(head.left);
        postPrint(head.right);
        System.out.print(head.val+" ");
    }


    //测试类
    public static void main(String[] args) {
        int[] pre={1,2,4,7,3,5,6,8};
        int[] in ={4,7,2,1,5,3,8,6};
        TreeNode root = reConBinaryTreeByPreAndIn.conBinaryTree(pre, in);
        reConBinaryTreeByPreAndIn.postPrint(root);
    }
}


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

根据中序+后序重构二叉树代码:


import java.util.Arrays;

public class reConBinaryTreeByPostAndIn {
    public static TreeNode conBinaryTree(int[] post,int[] in){
        if(post==null||in==null){
            return null;
        }
        if(post.length==0||in.length==0){
            return null;
        }
        if(post.length!=in.length){
            return null;
        }
        TreeNode root = new TreeNode(post[post.length-1]);
        for(int i=0;i<in.length;i++){
            if(root.val == in[i]){
                root.left=conBinaryTree(Arrays.copyOfRange(post,0,i),Arrays.copyOfRange(in,0,i));
                root.right=conBinaryTree(Arrays.copyOfRange(post,i,post.length-1),Arrays.copyOfRange(in,i+1,in.length));
            }
        }
        //构建二叉树完成   输出根节点
        return root;
    }

    //前序输出打印
    public static void prePrint(TreeNode head){
        if(head == null){
            return;
        }
        System.out.print(head.val+" ");
        prePrint(head.left);
        prePrint(head.right);
    }

    //测试类
    public static void main(String[] args) {
        int[] post ={7,4,2,5,8,6,3,1};
        int[] in ={4,7,2,1,5,3,8,6};
        TreeNode treeNode = reConBinaryTreeByPostAndIn.conBinaryTree(post, in);
        reConBinaryTreeByPostAndIn.prePrint(treeNode);
    }
}

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

在递归方法中调用了Arrays.copyOfRange(int[] m ,from,to)这个函数,是将m数组由from到to重新复制一份,是包括from不包括to,Arrays.copyOfRange(int[] m ,0,0))=[]  而也就是说递归的边界是当递归函数的参数中,(int[] m ,A,B),当A=B时,也就是  当pre和in   或者  post和in  两个数组一样时,他们的下次递归参数就成了 [] 因此也就返回null   说明该节点没有子节点了。递归结束。

猜你喜欢

转载自blog.csdn.net/weixin_43014205/article/details/85945094