题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
什么是二叉树?
二叉树(Binary Tree)是n(n≥0)个节点的有限集合,它或者是空集(n=0),或者是由一个根节点以及两棵互不相交的、分别称为左子树和右子树的二叉树组成。二叉树与普通有序树不同,二叉树严格区分左孩子和右孩子,即使只有一个子节点也要区分左右。
二叉树的遍历
遍历 :沿某条搜索路径周游二叉树,对树中的每一个节点访问一次且仅访问一次。
遇到没遍历的新节点都当根处理
先序遍历: 先访问树根,再访问左子树,最后访问右子树;根左右
中序遍历: 先访问左子树,再访问树根,最后访问右子树;左根右
后序遍历: 先访问左子树,再访问右子树,最后访问树根;左右根
层次遍历: 从根节点开始,逐层从左向右进行遍历。
使用Python实现二叉树
# 二叉树节点
class TreeNode:
def __init__(self, val=None, left=None, right=None):
self.val = val
self.left = left
self.right = right
# 二叉树操作
class Bitree:
def __init__(self, root=None):
self.root = root # 获取树根
# 先序遍历
def preOrder(self,node):
# 传入根节点
if node is None:
return
# 打印根节点数据
print(node.val,end=' ')
# 将根节点的左点节 作为根节点 递归调用自身,直至满足node is None,停止递归
self.preOrder(node.left)
self.preOrder(node.right)
# 中序遍历
def inOrder(self, node):
if node is None:
return
self.inOrder(node.left)
print(node.val, end=' ')
self.inOrder(node.right)
# 后序遍历
def postOrder(self, node):
if node is None:
return
self.postOrder(node.left)
self.postOrder(node.right)
print(node.val, end=' ')
if __name__ == "__main__":
# 后序遍历 BFGDIHECA
# 构建树
b = TreeNode('B')
f = TreeNode('F')
g = TreeNode('G')
d = TreeNode('D', f, g)
i = TreeNode('I')
h = TreeNode('H')
e = TreeNode('E', i, h)
c = TreeNode('C', d, e)
a = TreeNode('A', b, c) # 树根
# 初始化树对象,得到树根
bt = Bitree(a)
# 先序
bt.preOrder(bt.root)
print()
# 中序
bt.inOrder(bt.root)
print()
# 后序
bt.postOrder(bt.root)
print()
根据题目构建二叉树图
构建代码
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre: list, tin: list) -> object:
"""
pre: 前序列表
tin: 中序列表
"""
# write code here
if len(pre) == 0:
return None
if len(pre) == 1:
return TreeNode(pre[0])
else:
root = TreeNode(pre[0]) # 前序序列的第一个肯定是当前子树的根节点
rootid = tin.index(root.val) # 通过根节点在中序序列中的位置划分出左右子树包含的节点
root.left = self.reConstructBinaryTree(pre[1:rootid + 1], tin[:rootid])
root.right = self.reConstructBinaryTree(pre[rootid + 1:], tin[rootid + 1:])
return root
代码流程
对结果进行验证
完整代码
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre: list, tin: list) -> object:
"""
pre: 前序列表
tin: 中序列表
"""
# write code here
if len(pre) == 0:
return None
if len(pre) == 1:
return TreeNode(pre[0])
else:
root = TreeNode(pre[0]) # 前序序列的第一个肯定是当前子树的根节点
rootid = tin.index(root.val) # 通过根节点在中序序列中的位置划分出左右子树包含的节点
root.left = self.reConstructBinaryTree(pre[1:rootid + 1], tin[:rootid])
root.right = self.reConstructBinaryTree(pre[rootid + 1:], tin[rootid + 1:])
return root
class Bitree:
def __init__(self, root=None):
self.root = root # 获取树根
# 先序遍历
def preOrder(self, node):
# 传入根节点
if node is None:
return
# 打印根节点数据
print(node.val, end=' ')
# 将根节点的做点节 作为根节点 调用自身
self.preOrder(node.left)
self.preOrder(node.right)
# 中序遍历
def inOrder(self, node):
if node is None:
return
self.inOrder(node.left)
print(node.val, end=' ')
self.inOrder(node.right)
# 后序遍历
def postOrder(self, node):
if node is None:
return
self.postOrder(node.left)
self.postOrder(node.right)
print(node.val, end=' ')
if __name__ == '__main__':
s = Solution()
pre = [1, 2, 4, 7, 3, 5, 6, 8]
tin = [4, 7, 2, 1, 5, 3, 8, 6]
root = s.reConstructBinaryTree(pre, tin)
# 初始化树对象,得到树根
bt = Bitree(root)
# 先序
bt.preOrder(bt.root) # 1 2 4 7 3 5 6 8
print()
# 中序
bt.inOrder(bt.root) # 4 7 2 1 5 3 8 6
print()
# 后序
bt.postOrder(bt.root) # 7 4 2 5 8 6 3 1
print()
补充 代码实现二叉树层次遍历
'''
利用队列先进先出特性,实现二叉树层次遍历
'''
# 自定义队列异常
class QueueError(Exception):
pass
# 队列操作类
class SQueue:
def __init__(self):
self._elems = []
# 判断队列空
def is_empty(self):
return self._elems == []
# 入队 从列表尾部
def enqueue(self, elem):
self._elems.append(elem)
# 出队 从列表开头
def dequeue(self):
if not self._elems:
raise QueueError("Queue is empty")
return self._elems.pop(0)
# 二叉树节点
class TreeNode:
def __init__(self, val=None, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Bitree:
def __init__(self, root=None):
self.root = root # 获取树根
# 层次遍历
def levelOrder(self,node):
sq = SQueue()
sq.enqueue(node) # 从node遍历
while not sq.is_empty():
node = sq.dequeue() # 出队一个
print(node.val,end=' ') # 遍历数据
if node.left:
sq.enqueue(node.left)
if node.right:
sq.enqueue(node.right)
如有错误,欢迎指正