由于树可以转换为二叉树,故直接进行二叉树的学习。
二叉树
二叉树最多只有左子树和右子树两个子树,二叉树的性质如下:
- 在二叉树的第 层最多有 个节点
- 深度为 的二叉树最多有 个节点
- 对于任意一棵二叉树,如果叶节点数为 ,而度数为2的节点总数为 ,则有
- 具有 个节点的完全二叉树的深度必为
- 对完全二叉树,若从上至下、从左至右编号,则编号为 的结点,其左孩子编号必为 ,其右孩子编号必为 ;其双亲的编号必为 (除 外)
常用的二叉树有满二叉树和完全二叉树,满二叉树指除最后一层无任何子节点外,每一层上的所有结点都有两个子结点二叉树;完全二叉树指当二叉树的深度为 ,除第 层外,其它各层 的结点数都达到最大个数,第 层所有的结点都连续集中在最左边的二叉树。
满二叉树
完全二叉树
二叉树的实现:
from collection import deque
# 二叉树结点
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
# 二叉树
class Tree(object):
def __init__(self):
self.root = None
二叉树层序遍历:若树为空,则返回空,zh否则从根节点开始访问,从上而下逐层遍历。在同一层中按从左到右的顺序对节点逐个访问。若二叉树如下所示,则层序遍历的顺序为:ABCDEFGHI。
# 层序遍历
def bfs(self):
ret = []
queue = deque([self.root])
while queue:
node = queue.popleft()
if node:
ret.append(node.val)
queue.append(node.left)
queue.append(node.right)
return ret
二叉树前序遍历:若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。若二叉树如上图所示,遍历的顺序为:ABDGHCEIF。
# 前序遍历:根-左-右
def pre_traversal(self):
ret = []
def traversal(head):
if not head:
return
ret.append(head.val)
traversal(head.left)
traversal(head.right)
traversal(self.root)
return ret
二叉树中序遍历:若树为空,则空操作返回,否则从根结点开始(注意并不是先访问根结点),中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树。若二叉树如上图图所示,遍历的顺序为:GDHBAEICF。
中序遍历的结果一个很重要的特性:遍历结果自然就是升序的。
# 中序遍历:左-根-右
def in_traversal(self):
ret = []
def traversal(head):
if not head:
return
traversal(head.left)
ret.append(head.val)
traversal(head.right)
traversal(self.root)
return ret
二叉树后序遍历:若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访向左右子树,最后是访问根结点。若二叉树如上图所示,遍历的顺序为:GHDBIEFCA。
# 后序遍历:左-右-根
def post_traversal(self):
ret = []
def traversal(head):
if not head:
return
traversal(head.left)
traversal(head.right)
ret.append(head.val)
traversal(self.root)
return ret
根据前序遍历和中序遍历重建二叉树
df construct_tree(preorder=None, inorder=None):
if not preorder or not inorder:
return None
index = inorder.index(preorder[0])
# 左子树的中序遍历序列
left = inorder[0:index]
# 右子树的中序遍历序列
right = inorder[index+1:]
# 返回根节点
root = TreeNode(preorder[0])
# 递归调用重建二叉树
root.left = construct_tree(preorder[1:1+len(left)], left)
root.right = construct_tree(preorder[-len(right):], right)
return root