重建二叉树(Java)

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

struct BinaryTreeNode{
	int m_nValue;
	BinaryTreeNode* m_pLeft;
	BinaryTreeNode* m_pRight;
}

在前序遍历中最前面的数字为根节点,找到跟节点。
然后在中序遍历中确认根节点的位置,根节点左边为左子树,右边为右子树。
然后再次使用递归,确认左右子树。
递归过程中发现序列中只有一个节点时 则证明是叶子节点直接返回。

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if(pre==null || in==null || pre.length ==0 || in.length ==0){
            return null;
        }
        return construct(pre, in, 0, pre.length-1, 0, in.length-1);
    }
    
    private TreeNode construct(int [] pre, int [] in, int startIndexPre, int endIndexPre,
                                 int startIndexIn, int endIndexIn){
        //前序遍历找到跟节点
        TreeNode root = new TreeNode(pre[startIndexPre]);
        if(startIndexPre == endIndexPre){
            //考虑输入出错的情况
            if(startIndexIn == endIndexIn && in[startIndexIn] == in[endIndexIn]){   
                return root;
            }else{
                throw new RuntimeException("Invalid input.");
            }
        }
        //中序遍历区分左右子树进行递归
        int rootIndexInMid = startIndexIn;
        
        while (root.val != in[rootIndexInMid] && rootIndexInMid<= endIndexIn){
            rootIndexInMid++;
        }
        
        //考虑是否有找不到的情况
        if(rootIndexInMid > endIndexIn){
            throw new RuntimeException("Invalid Input");
        }
        int leftTreeLength = rootIndexInMid-startIndexIn;
        if(leftTreeLength >0){
            //递归左子树
            root.left = construct(pre, in , startIndexPre+1, startIndexPre+leftTreeLength, 
                                  startIndexIn, rootIndexInMid-1);
        }
        
        if(rootIndexInMid != endIndexIn){
            root.right = construct(pre, in , startIndexPre+leftTreeLength+1, endIndexPre, 
                                   rootIndexInMid+1, endIndexIn);
            //递归右子树
        }
        return root;       
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值