树的那些事儿——基本操作 中整理了一些树的基本操作。
这一篇开始就整理剑指offer中树的一些习题吧~
题目: 重建一棵树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
这个问题其实看起来并不困难。(类似的问题还右输入中序和后序遍历。。)
- 前序遍历:第一个值就是树的根结点。
- 中序遍历:以前序遍历的第一个值为界,左边是左子树,右边是右子树。
- 然后根据左右子树的序列长度,可以把前序遍历的左右子树序列划分开。
- 然后前序遍历左子树序列的第一个值是左子树的根结点。右子树序列的第一个值是右子树的根节点。。。
看出来了,就是个递归过程。
- 但是程序的关键主要是搞清楚索引下标。
那怎么搞清楚下标呢。画个图吧。
很清楚啦。中序中根节点的下标是index的话
- 前序:
- 左子树 : pre[1:index+1]
- 右子树: pre[index+1:]
- 中序:
- 左子树: tin[:index]
- 右子树:tin[index+1:]
然后递归就完事儿了
# 结点定义
class TreeNode():
def __init__(self,x):
self.val = x
self.left = None
self.right = None
# 重建一棵树
def reConstructBinaryTree(pre, tin):
# 检查输入长度
if len(pre) ==0:
return None
if len(pre) == 1:
return TreeNode(pre[0])
else:
root = TreeNode(pre[0])
# 划分系递归区间
index = tin.index(pre[0]) # 找到根在中序遍历的位置
# pre的左子树
pre_left = pre[1:index+1]
pre_right = pre[index+1:]
# tin的左子树
tin_left = tin[:index]
tin_right =tin[index+1:]
# 递归重建左子树
root.left = reConstructBinaryTree(pre_left,tin_left)
root.right = reConstructBinaryTree(pre_right,tin_right)
return root