剑指offer06,重建二叉树(Java实现)

题目要求是根据前序遍历和中序遍历打印二叉树,在这里我也写了中序和后序建树 ,前序和后序建树,如果有不对的地方请发邮件到995232184@qq.com。若是不太明白思路或者过程也可发邮件给我,我建议大家画好树再看代码,比较直观。

 

/*
     * 前序和中序建立二叉树
     */
    public TreeNode preInToTree(int[] pre, int[] in){
        if(pre == null || in == null){
            return null;
        }
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        for(int i = 0; i <in.length; i++){
            map.put(in[i], i);//map是<key, value>形式,在使用的过程中,经常将key方位有效数,value放索引
        }
        return preIn(pre, 0, pre.length-1, in, 0, in.length-1, map);
    }

    private TreeNode preIn(int[] p, int pi, int pj, int[] n, int ni, int nj, HashMap<Integer, Integer> map) {
        if(pi > pj){
            return null;  //先序数组中,前边的索引大于后边的索引,就退出
        }
        TreeNode head = new TreeNode(p[pi]);//每次的头结点,都是先序数组中的第一个,待会就返回这个
        int index = map.get(p[pi]);//在中序数组中找到头结点的索引
        head.left = preIn(p, pi+1, pi + (index - ni), n, ni, index - 1, map);  //中间的()只是为了帮助理解
        head.right = preIn(p, pi + (index - ni) + 1, pj, n, index + 1, nj, map); //中间的()只是为了帮助理解         
        return head;
    }
    
    /*
     * 中序和后序建立二叉树
     */
    public TreeNode inPosToTree(int[] in, int[] pos){
        if(in == null || pos == null){
            return null;
        }
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        for(int i = 0; i <in.length; i++){
            map.put(in[i], i);//map是<key, value>形式,在使用的过程中,经常将key方位有效数,value放索引
        }
        return inPos(in, 0, in.length-1, pos, 0, pos.length-1, map);
    }

    private TreeNode inPos(int[] n, int ni, int nj, int[] s, int si, int sj, HashMap<Integer, Integer> map) {
        if(si > sj){
            return null;
        }
        TreeNode head = new TreeNode(s[sj]);//每次的头结点,都是后序序数组中的最后一个,待会就返回这个
        int index = map.get(s[sj]);//在中序数组中找到头结点的索引
        head.left = inPos(n, ni, index - 1, s, si, si + (index - ni) -1, map);
        head.right = inPos(n, index + 1, nj, s, si + (index - ni), sj-1, map);
        return head;
    }
    
    /*
     * 根据前序和后序建立二叉树,需要分析一下什么时候可以建树
     * 如果一棵二叉树除叶结点外,其他所有的结点都有左孩子和右孩子,只有这样的树才能被先序和后序建立出来。
     * 最后才是通过划分左右子树各自的先序和后序数组的方式重建整棵树。
     */
    public TreeNode prePosToTree(int[] pre, int[] pos){
        if(pre == null || pos == null){
            return null;
        }
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        for(int i = 0; i < pos.length; i++){
            map.put(pos[i], i);
        }
        return prePos(pre, 0, pre.length-1, pos, 0, pos.length-1, map);
        
    }

    private TreeNode prePos(int[] p, int pi, int pj, int[] s, int si, int sj, HashMap<Integer, Integer> map) {
        TreeNode head = new TreeNode(s[sj--]);//取头结点
        if(pi == pj) return head;
        
        int index = map.get(p[++pi]); //通过先序数组去找后序数组中的索引
        head.left = prePos(p, pi, pi + (index - si), s, si, index, map);
        head.right = prePos(p, pi + (index - si) + 1, pj, s, index + 1, sj, map);
        return head;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值