菜鸡的算法修炼——二叉树(重建二叉树)

题目描述(引自剑指offer)

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

菜鸡与大佬的对话

有一回大佬对菜鸡说道,“你学过树型结构么?”

菜鸡略略点一点头。

大佬说,“学过树型结构,……我便考你一考。二叉树,怎样遍历的?”

菜鸡想,讨饭一样的人,也配考我么?便回过脸去,不再理会。

大佬等了许久,很恳切的说道,“不能遍历罢?……我教给你,记着!这些算法应该记着。将来做程序员的时候,写代码要用。”

菜鸡暗想,我和程序员的等级还很远呢,而且菜鸡修炼坊里都能查到;又好笑,又不耐烦,懒懒的答他道,“谁要你教,不是沿着某条搜索路线依次访问二叉树中的每个结点么?”

大佬显出极高兴的样子,将两个手指敲着计算机,点头说,“对呀对呀!……二叉树有四样遍历方式,你知道么?”

菜鸡愈不耐烦了,努着嘴走远。

大佬刚用手指点了点键盘,想在编辑器上写代码,见菜鸡毫不热心,便又叹一口气,显出极惋惜的样子。

——改编自鲁迅先生的《孔乙己》

菜鸡修炼坊

二叉树的遍历方式
定义
前序遍历
根结点->左子树->右子树
中序遍历
左子树->根结点->右子树
后序遍历
左子树->右子树->根结点
层次遍历
顶层(根)->底层(叶子),同层左->右


题目分析

在菜鸡修炼坊学习了二叉树的四种遍历之后,菜鸡进行了认真地思考。菜鸡发现,上次修炼的题目,采用右子树->根结点->左子树的遍历方式比上述四种遍历方式更加合适,因此,不要被既有的几种定义所限制,只是个名字而已。

根据四种遍历方式的定义,结合题目,菜鸡发现,在不含重复数字的前提下,通过前序遍历序列和中序遍历序列确实可以重建二叉树,同理,通过后序遍历序列和中序遍历序列也可以重建二叉树。因为中序遍历可以根据根结点的位置将左右子树加以区分,而且这个过程是可递归的。基于这个原理,可以发现,通过前序遍历序列和后序遍历序列则不能重建二叉树。

在搞清楚了重建二叉树的原理之后,菜鸡决定用Java代码实现他的心路历程。

代码实现

// 二叉树的定义
public class TreeNode {
    int value = 0;
    TreeNode left = null;
    TreeNode right = null;


    public TreeNode(int value) {
        this.value = value;
    }
}
import java.util.Arrays;


public class Solution {


    // 重建二叉树
    public TreeNode reConstructBinaryTree(int[] preOrder, int[] inOrder) {
        // 判断入参
        if (preOrder == null || preOrder.length == 0) {
            return null;
        }
        TreeNode root = new TreeNode(preOrder[0]);
        int rootIndex = 0;
        // 寻找中序遍历序列中根结点所在的位置
        for (int i = 0; i < inOrder.length; i++) {
            if (inOrder[i] == preOrder[0]) {
                rootIndex = i;
                break;
            }
        }
        // 递归重建左子树
        root.left = reConstructBinaryTree(Arrays.copyOfRange(preOrder, 1, rootIndex + 1), Arrays.copyOfRange(inOrder, 0, rootIndex));
        // 递归重建右子树
        root.right = reConstructBinaryTree(Arrays.copyOfRange(preOrder, rootIndex + 1, preOrder.length), Arrays.copyOfRange(inOrder, rootIndex + 1, inOrder.length));
        // 返回根结点
        return root;
    }
    
}

经过修炼之后,菜鸡发现前序遍历,中序遍历和后序遍历是递归定义的,因此实现方式可以采用递归和非递归两种方式。经过一番研究学习,菜鸡发现这四种遍历方式都蕴含了非常深刻的思想,确实值得牢记。菜鸡突然开始后悔今天面对大佬时的表现,他决定痛改前非,继续虚心修炼……

相关链接

菜鸡的算法修炼——二叉搜索树(二叉搜索树与双向链表)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值