题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
关于树的概念:
树是一种在实际编程中经常遇到的数据结构。它的逻辑很简单:除根节点之外每个节点只有一个父节点,根节点没有父节点;除叶节点之外所有的节点都有一个或多个子节点,叶节点没有子节点。父节点和子节点之间用指针链接。
面试的时候提到的树,大部分是二叉树。所谓二叉树是树的一种特殊结构,在二叉树中每个节点最多只有两个子节点。
在二叉树中最重要的操作莫过于遍历,即按照某一顺序访问树中的所有子节点。
通常树有如下几种遍历方式:
- 前序遍历:先访问根结点,再访问左子结点,最后访问右子结点。
- 中序遍历:先访问左子结点,再访问根结点,最后访问右子结点。
- 后序遍历:先访问左子结点,再访问右子结点,最后访问根结点。
- 宽度优先遍历:先访问树的第一层节点,再访问树的第二层节点...一直到访问到最下面一层节点。
二叉树有很多特例,二叉搜索树就是其中之一。在二叉搜索树中,左子节点总是小于或等于根节点,而右子节点总是大于或等于根子节点。
二叉树的另外两个特例是堆和红黑树。堆分为最大堆和最小堆。在最大堆中根节点的值最大,在最小堆中根节点的值最小。有很多需要快速找到最大值或者最小值的问题都可以用堆来解决。红黑树是把树中的节点定义为红、黑两种颜色,并通过规则确保从根节点到叶节点的最长路径的长度不超过最短路径的两倍。
思路:
前序遍历序列中,第一个数字总是树的根结点的值。在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边。剩下的我们可以递归来实现。
程序实现:
# -*- coding:utf-8 -*- # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: # 返回构造的TreeNode根节点 def reConstructBinaryTree(self, pre, tin): # write code here if len(pre)==0: return None elif len(pre)==1: return TreeNode(pre[0]) else: root = TreeNode(pre[0]) pos = tin.index(pre[0]) root.left = self.reConstructBinaryTree(pre[1:pos+1],tin[:pos]) root.right = self.reConstructBinaryTree(pre[pos+1:],tin[pos+1:]) return root