sword-06 根据先序遍历和中序遍历重建二叉树

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

ANY:
前序遍历(又称先序遍历):根左右
中序遍历:左根右
前序遍历的第一个节点一定是根节点由此可得出左子树为472,根节点1,右子树为5386,由此不断递归重建

public class Sword06 {


    public static void main(String[] args) {
        int[] pre = {1, 2, 4, 7, 3, 5, 6, 8};
        int[] mid = {4, 7, 2, 1, 5, 3, 8, 6};
        BinTreeNode<Integer> binTreeNode = reBuildIntegerBinaryTreeNode(pre,
                0,
                pre.length - 1,
                mid,
                0,
                mid.length - 1);
        System.out.println("先序遍历:");
        BinTreeSearch.preSearch(binTreeNode);
        System.out.println("\n中序遍历:");
        BinTreeSearch.midSearch(binTreeNode);
    }

    /**
     * 根据先序遍历序列和中序序列构建二叉树
     *
     * @param pre           先序遍历序列
     * @param preStartIndex 先序开始位置
     * @param preEndIndex   先序结束位置
     * @param mid           中序遍历序列
     * @param midStartIndex 中序开始位置
     * @param midEndIndex   中序结束位置
     * @return
     */
    private static BinTreeNode<Integer> reBuildIntegerBinaryTreeNode(int[] pre,
	                                                                     int preStartIndex,
	                                                                     int preEndIndex,
	                                                                     int[] mid,
	                                                                     int midStartIndex,
	                                                                     int midEndIndex) {
	        //防止越界
	        if (preStartIndex > preEndIndex || midStartIndex > midEndIndex) {
	            return null;
	        }
	        //先序遍历第一个元素即为根节点
	        int rootVal = pre[preStartIndex];
	        BinTreeNode<Integer> rootNode = new BinTreeNode<>(rootVal);
	        //递归结束,依次返回
	        if (preStartIndex == preEndIndex || midStartIndex == midEndIndex) {
	            return rootNode;
	        }
	        //在中序遍历序列中寻找此根节点位置
	        int rootPostion = midStartIndex;
	        while (rootPostion <= midEndIndex && mid[rootPostion] != rootVal) {
	            rootPostion++;
	        }
	        //中序遍历序列不存在的根节点,说明中序遍历序列有问题
	        if (rootPostion > midEndIndex) {
	            throw new RuntimeException("中序遍历序列有错误!");
	        }
	        //计算中序中寻找根节点的步数
	        int stepCount = rootPostion - midStartIndex;
	        //先序遍历序列中左子树的开始位置为preStartIndex + 1,结束位置为preStartIndex + stepCount
	        //中序遍历序列中左子树的开始位置为midStartIndex,结束位置为rootPostion+1
	        rootNode.setLeftBinTreeNode(reBuildIntegerBinaryTreeNode(
	                pre,
	                preStartIndex + 1,
	                preStartIndex + stepCount,
	                mid,
	                midStartIndex,
	                rootPostion - 1
	        ));
	        //先序遍历序列中左子树的开始位置为preStartIndex + stepCount + 1,结束位置为preEndIndex
	        //中序遍历序列中左子树的开始位置为rootPostion + 1,结束位置为midEndIndex
	        rootNode.setRightBinTreeNode(reBuildIntegerBinaryTreeNode(
	                pre,
	                preStartIndex + stepCount + 1,
	                preEndIndex,
	                mid,
	                rootPostion + 1,
	                midEndIndex
	        ));
	        return rootNode;
	    }
	
	
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class BinTreeNode<T> {
    private T val;
    private BinTreeNode<T> rightBinTreeNode;
    private BinTreeNode<T> leftBinTreeNode;

    public BinTreeNode(T val) {
        this.val = val;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值