二叉树:还原二叉树

    一、根据先序和中序遍历结果,还原二叉树。如给定先序访问结果[3, 9, 20, 15, 7]和中序访问结果[9, 3, 15, 20, 7],还原出二叉树如下.


    分析:先序访问的第一个元素必然是root节点,而中序访问时,root元素是左子树和右子树的分界点,同时,先序也是先访问左子树再访问右子树。因此,可以根据先序结果知道root,然后可以根据root节点把中序的结果分成左子树和右子树,再根据左子树元素个数和右子树元素个数,把先序结果也分成左子树和右子树。依次递归,即可得到结果。

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder.length == 0)
            return null;
        TreeNode root = new TreeNode(preorder[0]);
        if(preorder.length == 1)    //叶子
            return root;
        int i;
        for(i = 0; i < preorder.length; i++){  //寻找中序的分界点
            if(inorder[i] == preorder[0]) break;
        }
        root.left = buildTree(Arrays.copyOfRange(preorder, 1, i + 1), Arrays.copyOfRange(inorder, 0, i));
        root.right = buildTree(Arrays.copyOfRange(preorder, i + 1, preorder.length), Arrays.copyOfRange(inorder, i + 1, inorder.length));
        return root;
    }

    二、根据中序和后续访问结果,还原二叉树,同样的思路。

  public TreeNode buildTree(int[] inorder , int[] postorder) {
       if(postorder.length == 0)
           return null;
       return build(0, postorder.length - 1, 0, inorder.length - 1, postorder, inorder);
   }
   public TreeNode build(int pl, int ph, int il, int ih, int[] postorder, int[] inorder){
       if(pl > ph || il > ih)    //需判断,并返回null,否则如果节点的右儿子为空时的会出错
		   	return null;
       TreeNode root = new TreeNode(postorder[ph]);
       if(ph == pl)
           return root;
       int i;
       for(i = ih; i > il; i--){
           if(inorder[i] == postorder[ph]) break;
       }
       root.left = build(pl, pl + i - il - 1, il, i - 1, postorder, inorder);    //注意postorder数组的边界,不能直接以i为参照,而应以postorder的下边界加上子数组的长度,否则当inorder中间有root节点时会出错
       root.right = build(pl + i - il, ph - 1, i + 1, ih, postorder, inorder);
       return root;
   }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值