二叉树之重建二叉树

1.本题知识点
   二叉树,递归
2. 题目描述
  输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
3. 概念解析
   ① 什么是二叉树?
     二叉树是每个结点最多有两个子树的树结构。二叉就是只有左右两条路径。
   ② 二叉树的遍历方式有哪些?
     深度优先搜索DFS:先序遍历、中序遍历、后序遍历。
     广度优先搜索BFS:层序遍历。
4. 思路
   整理思路:根据先序和中序序列来构建树及其左右子树。
   ★ 主要步骤分两点:
   No.1 首先在先序序列中确定root节点,此时,树的根节点确定了。
   No.2 在中序序列中寻找root节点,找到之后通过递归构造左右子树,此时,树的左右子树确定了。
   No.3 综上,此时当前树的结构就构建好了。对于left和right子树用同样的方式构建即可(递归)。(对于二叉树,一般都是只同时考虑root、left、right)
   关键点:为了确定数组中的左右子树,所以要计算先序和中序start和end索引值。那么如何计算呢?
   ① 中序的start和end索引值很好确定,肉眼看就可以。
   ② 先序的start end索引则根据中序确定的左子树长度来计算。
   比如,计算左子树的索引,如下图,中序root索引为rootIndex = 3,左子树长度LeftLen = 3,则中序的左子树索引 0 ~ rootIndex-1,先序的左子树索引为 0 + (rootIndex - 0)(前序的start索引 + 中序中左子树的长度)。如果还不明白可看下图和代码。

在这里插入图片描述

   Java版本:

/**
 * 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) {
        TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
        return root;
    }
    //前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
    //pre前序列表,mid 中序列表,
    //startPre前序的开始序列,endPre前序的结束序列
    //startMid 中序的开始序列,endMid 中序的结束序列
    // ===========================================
    //【整理思路】:根据先序和中序序列来构建树及其左右子树
    private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,
                                           int [] mid,int startMid,int endMid) 
    {
        //左右子树构建完成
        if(startPre>endPre||startMid>endMid)
            return null;
        //1、先序遍历中确定root节点
        TreeNode root=new TreeNode(pre[startPre]);
        //2、中序遍历中寻找root节点,然后构建当前root的左右子树root.left root.right,
        for(int i = startMid;i <= endMid;i++)
        {
            //3、中序遍历找到root节点后,确定了左右子树的节点列表,然后用同样的方式(递归)构建左右子树即可
            if(mid[i] == pre[startPre]){
                //4、关键点:理解先序和中序start和end索引值的计算
                //中序的start end很好计算
                //先序的start end计算方式: 先计算中序的左子树长度,再根据这个长度i-startMid计算先序的start end
                //startPre+(i-startMid)为先序中左子树的end位置,再加上1就是先序的右子树start索引值
                root.left=reConstructBinaryTree(pre,startPre+1,startPre+(i-startMid),mid,startMid,i-1);
                root.right=reConstructBinaryTree(pre,startPre+(i-startMid)+1,endPre,mid,i+1,endMid);
                break;
            }
        }
        
        return root;
   }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值