从前序与中序遍历序列构造二叉树
首先要知道,先序遍历的顺序为[ 左、中、右 ],中序遍历的顺序为[ 中、左、右 ]。
对于一棵树:
3
/ \
2 5
/ \
4 6
中序遍历的结果是[3,2,5,4,6] ,记住每颗子树都是从根开始。
左序遍历的结果是[2,3,4,5,6], 记住每棵树都是从左到根再到右,这就是有序树的关键。
所以对于题目:
前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7]
根节点就是[3], 根节点也把中序遍历的结果分成两部分[9]、[3]、[15,20,7]。
设根节点索引为j, 由此得知:
inorder 左子树对应的序列为[0 : j], 右子树对应的序列为[j+1: ]
preorder左子树对应的序列为[1: j+1], 右子树对应的序列为[j+1: ]
然后对子树递归调用,得知子树的子树的根节点和左右序列,由下往上构成一颗树。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def buildTree(self, preorder, inorder):
"""
:type preorder: List[int]
:type inorder: List[int]
:rtype: TreeNode
"""
if len(preorder) == 0:
return None
root_node = TreeNode(preorder[0]) # 初始化根节点
j = inorder.index(root_node.val) # 根据根节点的值获取在inorder中索引
root_node.left = self.buildTree(preorder[1:j+1],inorder[0:j])
root_node.right = self.buildTree(preorder[j+1:],inorder[j+1:])
return root_node
从后序与中序遍历序列构造二叉树
道理其实一样,后序遍历的末尾元素肯定是肯节点了。找到根节点后,计算左右字树左右个数然后划分两个序列。
中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3]
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def buildTree(self, inorder, postorder):
"""
:type inorder: List[int]
:type postorder: List[int]
:rtype: TreeNode
"""
if len(postorder) == 0:
return None
root = TreeNode(postorder[-1])
j = inorder.index(root.val)
root.left = self.buildTree(inorder[0:j], postorder[0:j])
root.right = self.buildTree(inorder[j+1:], postorder[j:-1])
return root
对于一般树的标准先序、后序和广度优先遍历能直接应用在二叉树中。而中序遍历最主要是用在二叉搜索树的数据结构,即把有序序列元素存储在二叉树中。例如上面的那颗可爱的小树。二叉搜索树的运行时间和高度成正比,所以当二叉树高度最小时效率最高。