剑指Offer:重建二叉树【7】

剑指Offer:重建二叉树【7】

题目描述

  输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

  例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

题目分析

  首先我们要了解前序和中序遍历的特点

 

  从图中不难发现,对于前序遍历的第一个节点1,在中序遍历中处于中间位置,且两侧分别对应他的左右子树。这是因为中序遍历打印的顺序为:左孩子——当前元素——右孩子,而前序遍历是首先打印当前元素。

  重建二叉树的重构函数分为三个步骤

  • 首先要找到当前元素节点,即pre中的第一个,
  • 接着在中序遍历中找到它的左右子树(此处表现为对前序数组、中序数组的分割操作),以便构造他的左右孩子。
  • 最后再将左右子树在分别放到重构函数中

  比如此时,我们找到1的右子树(356),如下图,它实质上适合上图一样的,只不过此时是以3位根节点,其他操作是一样。

  

 

  此时重复操作:找到当前元素节点,即pre中的第一个,接着便可以在中序遍历中找到他的左右子树,以便构造他的左右孩子。发现他没有右孩子,只有左孩子,那就将左孩子放入重构函数中,即

 

  

  此时重复操作:找到当前元素节点,即pre中的第一个,接着便可以在中序遍历中找到他的左右子树,以便构造他的左右孩子。发现他没有右孩子,只有左孩子,那就将左孩子放入重构函数中,即

 

 

 

  直到分割成叶子节点,不存在左右子树,他无法再进行分割,故返回自己。叶子节点返回后,其父节点的左右子树分别有了指向,便返回,一步一步向上返回,最后会返回整个二叉树

 

 

Java实现代码

public class BuildTree {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        TreeNode root=ConstructCore(pre,0,pre.length-1,in,0,in.length-1);
        return root;
    }

    public TreeNode ConstructCore(int[] pre,int startPre,int endPre,int[] in,int startIn,int endIn)
    {
        if(startPre>endPre||startIn>endIn)
            return null;
        TreeNode node = new TreeNode(pre[startPre]);
        for(int i=startIn;i<=endIn;i++)
        {
            if(in[i]==pre[startPre])
            {
                node.left = ConstructCore(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);
                node.right =ConstructCore(pre,startPre+i-startIn+1,endPre,in,i+1,endIn);
                break;
            }
        }
        return node;

    }
}

class TreeNode {
     int val;
     TreeNode left;
     TreeNode right;
     TreeNode(int x) { val = x; }
 }

  

 

posted @ 2018-06-20 18:53  子烁爱学习  阅读(1219)  评论(2编辑  收藏  举报