面试题7: 重建二叉树---Android端实现方式

题目:

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

分析

1. 前序遍历和中序遍历的过程要明白(根节点的输出次序,前序:根-左-右; 中序:左-根-右)

2. 对于每个节点都可理解为其有左子树和右子树,即使为空

3. 递归形式处理

代码实现 : 代码部分含有注释可自行理解

    /**
     * 根据前序遍历和中序遍历重新构建二叉树
     *
     * @param DLRList  前序遍历数组
     * @param startDLR 前序数组的开始位置
     * @param endDLR   前序数组的结束位置
     * @param LDRList  中序遍历数组
     * @param startLDR 中序数组的开始位置
     * @param endLDR   中序数组的结束位置
     * @return 返回当前二叉树的根节点
     */
    private TreeNode getRoot(int[] DLRList, int startDLR, int endDLR,
                             int[] LDRList, int startLDR, int endLDR) {
        if (DLRList == null || LDRList == null) {
            // 如果前序数组和中序数组都不存在,则返回空
            return null;
        }
        // 定义二叉树实体时value值设为了String,所以在这需要转换一下
        TreeNode rootNode = new TreeNode(String.valueOf(DLRList[startDLR]));
        // 定义左子树
        TreeNode leftNode = null;
        // 定义右子树
        TreeNode rightNode = null;
        if (startDLR == endDLR && startLDR == endLDR) {

            /**
             *  如果前序数组的开始位置等于结束位置并且中序数组的开始位置等于结束位置,
             *  则直接返回这个节点即可(无其他的左子树或者右子树)
             */
            return rootNode;
        }
        /**
         * 遍历中序数组,起始位置为中序的起始位置(startLDR),得到当前节点在中序数组
         * 中的位置,以便统计左子树节点数量和右子树节点数量
         */
        int rootLocation = startLDR;
        for (; rootLocation < LDRList.length; rootLocation++) {
            /**
             * 如果当前前序数组的第一个节点值等于中序数组中的某一值
             * 则判定当前位置rootLocation即为中序中根节点的位置
             */
            if (DLRList[startDLR] == LDRList[rootLocation]) {
                break;
            }
        }

        // 根据中序数组中的节点位置计算,当前节点的左子树的数量
        int leftLength = rootLocation - startLDR;
        // 根据中序数组中的节点位置计算,当前节点的右子树的数量
        int rightLenth = endLDR - rootLocation;
        if (leftLength > 0) {
            /**
             * 如果有左子树,则进入递归模式
             *  注意的是前序数组和中序数组不变,变化的是各个数组的起始位置
             *  前序数组: DLRList, 开始位置 startDLR + 1,
             *  结束位置:(前序数组中左子树结束位置)startDLR + leftLength
             *  中序数组:LDRList, 开始位置 startLDR,
             *  结束位置:(中序中左子树的结束位置) rootLocation - 1
             */
            leftNode = getRoot(DLRList, startDLR + 1, startDLR + leftLength,
                    LDRList, startLDR, rootLocation - 1);
            rootNode.setLeft(leftNode);
        }
        if (rightLenth > 0) {
            /**
             * 如果有右子树,则进入递归模式
             *  注意的是前序数组和中序数组不变,变化的是各个数组的起始位置
             *  前序数组: DLRList,
             *  开始位置:(前序中右子树的开始位置) startDLR + leftLength + 1,
             *  结束位置:(前序数组中的末尾位置)endDLR
             *  中序数组:LDRList,
             *  开始位置:(中序中右子树的开始位置)rootLocation + 1,
             *  结束位置:(中序中右子树的结束位置) endLDR
             */
            rightNode = getRoot(DLRList, startDLR + leftLength + 1, endDLR,
                    LDRList, rootLocation + 1, endLDR);
            rootNode.setRight(rightNode);
        }
        // 返回生成的节点
        return rootNode;

    }

    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Heynchy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值