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

涉及到树的基础。
前序 遍历,就是先遍历根部,在遍历左子节点和右子节点。
中序是先遍历左子树,再遍历根部,最后遍历右子节点。

所以在前序给出的第一数字就是根节点。然后在中序遍历中,找到这个数,那么这个数的左边,都是这个根节点的左子树。

第一步要在前序遍历中找到第一个节点。
第二步从中序遍历中找到这个节点。
第三步找到左子树右子树
第四步递归循环

package question7_build_tree;

/**
 * @Classname Solution2
 * @Description TODO
 * @Date 2020/3/31 15:28
 * @Created by mmz
 */
public class Solution2 {
    static class TreeNode{
        int root;
        TreeNode left = null;
        TreeNode right = null;

        public TreeNode(int root) {
            this.root = root;
        }

        @Override
        public String toString() {
            return "TreeNode{" +
                    "root=" + root +
                    ", left=" + left +
                    ", right=" + right +
                    '}';
        }
    }

    static TreeNode rebuildTree(int[] front,int frontstart,int frontend,int[] middle,int middlestart,int middleend){
        if(frontstart>frontend ||middlestart>middleend){
            return null;
        }
        TreeNode root = new TreeNode(front[frontstart]);
        int index = 0;
        for(int i = middlestart;i<=middleend;++i){
            if(front[frontstart] == middle[i]){
                index = i;
                break;
            }
        }
        root.left = rebuildTree(front,frontstart+1,frontstart+index-middlestart,middle,middlestart,index-1);
        root.right = rebuildTree(front,frontstart+index+1,frontend,middle,index+1,middleend);
        return root;
    }

    public static void main(String[] args) {
        int[] pre =new int[]{1,2,4,7,3,5,6,8};
        int[] mid = new int[]{4,7,2,1,5,3,8,6};
        System.out.println(rebuildTree(pre,0,pre.length-1, mid,0,mid.length-1));
    }
}

这题有一个问题,就是这个7这个节点,是4的右子树还是2的右子树呢。这样都能说得过去,是不是说明如果知道了前序与中序遍历,也不能确定这个二叉树的形状呢。


package question7_重建二叉树根据前序和中序;

/**
 * @Classname Main
 * @Description TODO
 * @Date 2020/4/11 15:21
 * @Created by mmz
 */
public class Main {
    public static class TreeNode{
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int val){
            this.val = val ;
        }

        @Override
        public String toString() {
            return "TreeNode{" +
                    "val=" + val +
                    ", left=" + left +
                    ", right=" + right +
                    '}';
        }
    }
    public static TreeNode Core(int[] front,int fs,int fe, int[] mid,int ms,int me){
        if(fs>fe || ms>me){
            return null;
        }
        TreeNode root = new TreeNode(front[fs]);
        int index =0;
        for(int i= 0;i<front.length;++i){
            if(front[fs] == mid[ms+i]){
                index = i;
                break;
            }
        }
        root.left = Core(front,fs+1,fs+index,mid,ms,ms+index-1);
        root.right = Core(front,fs+index+1,fe,mid,ms+index+1,me);
        return root;
    }

//    private static TreeNode help(int[] preorder, int pStart, int pEnd, int[] inorder, int iStart, int iEnd) {
//        //递归的第一步:递归终止条件,避免死循环
//        if (pStart > pEnd || iStart > iEnd) {
//            return null;
//        }
//        //重建根节点
//        TreeNode treeNode = new TreeNode(preorder[pStart]);
//        int index = 0;  //index找到根节点在中序遍历的位置
//        while (inorder[iStart + index] != preorder[pStart]) {
//            index++;
//        }
//        //重建左子树
//        treeNode.left = help(preorder, pStart + 1, pStart + index, inorder, iStart, iStart + index - 1);
//        //重建右子树
//        treeNode.right = help(preorder, pStart + index + 1, pEnd, inorder, iStart + index + 1, iEnd);
//        return treeNode;
//
//    }

    public static void main(String[] args) {
        int[] pre =new int[]{1,2,4,7,3,5,6,8};
        int[] mid = new int[]{4,7,2,1,5,3,8,6};
        System.out.println(Core(pre,0,pre.length-1,mid,0,mid.length-1));
//        System.out.println(help(pre,0,pre.length-1,mid,0,mid.length-1));

    }


}


自己完整的写出来了,问题在于index的计算,是往上加好呢,还是直接得到根节点的索引,我发现,还是index是用计数器内种,往上加好算,这样可以判断,进行遍历啊。
至于前序和中序数组的循环条件。
前序的左子节点,永远是fs+1,fs+index
中序是ms,ms+index-1



一定记住两个左右子树的判断条件
left = 前序数组 数组fs+1 fs+index
中序数组 数组ms ms+index-1

right = 前序数组 数组fs+index+1 fe
中序数组 数组ms+index+1 me

return完事

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值