重建二叉树

问题描述

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

算法

1、根据前序遍历序列第一个节点确定根节点(root)
2、根据根节点在中序序列中的位置分割出左右两个子序列
3、对左子树和右子树分别递归使用同样的方法继续分解

分析

切割1的左右子树

在这里插入图片描述

分析1的左子树

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

分析1的右子树

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

合成分析左右子树

在这里插入图片描述

代码

package ATree;


import java.util.Arrays;

/**
 * @Author Zhou  jian
 * @Date 2020 ${month}  2020/3/13 0013  14:15
 *
 * 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
 * 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
 * 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},
 * 则重建二叉树并返回。

 */
public class Problem1 {




    public TreeNode reConstructBinaryTree1(int [] pre,int [] in) {
        //健壮性检查
        if(pre.length == 0||in.length == 0){
            return null;
        }

        //在前序遍历中先找到根节点
        TreeNode node = new TreeNode(pre[0]);

        //在中序遍历中找到前序的根
        //这样就可以确定左子树的前序和左子树的中序
        //            右子树的前序和右子树的中序
        //不断递归     对左子树进行重建,对右子树进行重建
        //
        for(int i = 0; i < in.length; i++){
            if(pre[0] == in[i]){
                //左子树,注意copuOfRange函数,左闭右开
                node.left = reConstructBinaryTree1(Arrays.copyOfRange(pre, 1, i+1), Arrays.copyOfRange(in, 0, i));
                //右子树,注意copuOfRange函数,左闭右开
                node.right = reConstructBinaryTree1(Arrays.copyOfRange(pre, i+1, pre.length), Arrays.copyOfRange(in, i+1,in.length));
            }
        }
        return node;
    }

    public static void main(String[] args) {
            int[] prev = {1,2,4,7,3,5,6,8};
            int[] in = {4,7,2,1,5,3,8,6};
            Problem1 problem1=new Problem1();

           TreeNode  head=  problem1.reConstructBinaryTree1( prev, in);

           //前序遍历
            head.preOrder();
        System.out.println();
            //中序遍历
            head.middleOrder();
    }


}
class TreeNode {

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

    //前序遍历
    public void preOrder(){
        System.out.print(this.val+" ");
        if(this.left!=null){
            this.left.preOrder();
        }

        if(this.right!=null){
            this.right.preOrder();
        }
    }



    //中序遍历
    public void middleOrder(){
        if(this.left!=null){
            this.left.middleOrder();
        }
        System.out.print(this.val+" ");


        if(this.right!=null){
            this.right.middleOrder();
        }
    }


}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值