根据前序遍历序列和中序遍历序列构造二叉树算法(*)

一个前序遍历序列和一个中序遍历序列可以确定一颗唯一的二叉树。

根据前序遍历的特点, 知前序序列(PreSequence)的首个元素(PreSequence[0])为二叉树的根(root),
然后在中序序列(InSequence)中查找此根(root), 根据中序遍历特点, 知在查找到的根(root) 前边的序列为根的左子树的中序遍历序列,
后边的序列为根的右子树的中序遍历序列。 设在中序遍历序列(InSequence)根前边有left个元素. 则在前序序列(PreSequence)中,
紧跟着根(root)的left个元素序列(即PreSequence[1…left]) 为根的左子树的前序遍历序列, 在后边的为根的右子树的前序遍历序列.
而构造左子树问题其实跟构造整个二叉树问题一样,只是此时前序序列为PreSequence[1…left]), 中序序列为InSequence[0…left-1],
分别为原序列的子串, 构造右子树同样, 显然可以用递归方法解决。
在这里插入图片描述
代码:

/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    int preorder[],inorder[];
    Map<Integer,Integer> map;
    public TreeNode dfs(int pl,int pr,int ol,int or){
        if(pl > pr) return null;
        TreeNode res = new TreeNode(preorder[pl]);
        int iidex = map.get(res.val);
        res.left = dfs(pl+1,pl+iidex-ol,ol,iidex - 1);
        res.right = dfs(pl-ol+iidex+1,pr,iidex+1,or);
        return res;
    }
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        this.preorder = preorder;
        this.inorder = inorder;
        map = new HashMap<Integer,Integer>();
        for(int i = 0;i < inorder.length;i++)map.put(inorder[i],i);
        return dfs(0, preorder.length - 1,0 , inorder.length -1 );
    }
}

另一种解法加验证:

import org.omg.Messaging.SYNC_WITH_TRANSPORT;

public class E{
    public static class Tree{
        int val;
        Tree right;
        Tree left;

    }
    public static void  inorderlook(Tree tree){
        if(tree!=null){
            inorderlook(tree.left);
          System.out.print(tree.val+" ");
            inorderlook(tree.right);
        }
    }
    public static void prelook(Tree tree){
        if(tree!=null){
            System.out.print(tree.val+" ");
            prelook(tree.left);
            prelook(tree.right);
        }
    }
    public static Tree constructor(int []pre,int[]in){
        if(pre==null||in==null||pre.length!=in.length){
            return null;
        }
        return constructor(pre,0,pre.length-1,in,0,in.length-1);
    }

    private static Tree constructor(int[] pre, int ps, int pe, int[] in, int is, int ie) {
        if(ps>pe){
            return null;
        }
        int val1 = pre[ps];
        int index=is;
//        for(;index <=ie;index++){
//            if(in[index]==val1){
//                break;
//            }
//        }
        while(index<=ie & in[index]!=val1){
            index++;
        }
        Tree tree = new Tree();
        tree.val = val1;
        tree.left=constructor(pre,ps+1,index+ps-is,in,is,index-1);
        tree.right=constructor(pre,ps+index-is+1,pe,in,index+1,ie);
        return tree;
    }

    public static void main(String[] args) {
        int[] preorder = {1, 2, 4, 7, 3, 5, 6, 8};
        int[] inorder =  {4, 7, 2, 1, 5, 3, 8, 6};
        Tree tree =constructor(preorder,inorder);
        inorderlook(tree);
        System.out.println();
        prelook(tree);
    }
}

结果:


4 7 2 1 5 3 8 6 
1 2 4 7 3 5 6 8 
Process finished with exit code 0

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值