剑指offer2笔记之重建二叉树

前言

树是一种在实际编程中经常遇到的数据结构。它的逻辑结构很简单:除了根节点以外,每个节点只有一个父节点;除叶节点之外所有节点都有一个或多个子节点。父节点和子节点之间用指针链接。由于树会涉及到大量的指针,因此与树有关的面试题成为了面试官的青睐。
那么需要掌握哪些?就其中一部分来说,关于树的三大遍历方式:前序遍历、中序遍历、后序遍历都必须掌握,并且由于每种遍历方式都有递归和循环两种实现方式,因此我们需要掌握三种遍历六种实现方式。

后期需要掌握的我们后面再提…

题目描述(重建二叉树)

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

解题思路

首先,重建一棵二叉树,我们可以通过树的两种遍历方式推出树的结构,其中中序遍历是必不可少的序列。
题目给定的是前序遍历和中序遍历,我们知道在前序序列中第一个值root 一定是根节点,而这个 root 所在的中序序列中也是根节点,那么根据前序遍历的特性—先根再左再右,我们知道左右子树的序列一定从前序序列的root的下一个位置开始,而中序遍历的特性是—先左再根再右,那么,对于中序序列,左子树的中序序列从第一个位置到 root 的前一位置的范围内,而右子树的中序序列则从 root 的下一位置到末位置。再者,无论是前序序列还是中序序列,前序序列的左子树序列长度一定等于中序序列的左子树序列长度,右子树亦是。最后其实我们分别得到了 root 节点的左子树对应的前序序列和中序序列,以及右子树对应的前序序列和中序序列。

关键的地方来了,我们还需要对左子树和右子树进行重建二叉树,我们发现这个过程已经在以根节点为 root 的二叉树上走过了,只是序列长度缩短了,那么我们其实可以再次调用一次这个过程(函数),只要确定左右子树前序和中序序列的范围即可,那么这个过程其实就是利用树的递归特性。而递归的出口就是处理好叶节点的创建。
一个形象的图例:

算法实现

建立树的数据结构

重建二叉树

复杂度分析

时间复杂度

每次在中序遍历序列中找到根节点的位置需要 O(n) 的查找时间。
则T(n)=2T(2/n)+O(n),(两个子问题的时间加中序序列上的查找时间)那么T(n)=O(nlogn)。

空间复杂度

由于每个节点都会被递归到,所以递归栈需要 O(n) 的空间。

参考

<<剑指offer2>>

-------------本文结束感谢您的阅读-------------