1 二叉树的遍历
二叉树的遍历都是根据父结点的顺序位置来命名的。
1.1 先序遍历
先遍历父结点,再遍历左子结点最后遍历右子结点。上述树的遍历顺序为:5 2 1 3 7 6 8
递归版本:
@staticmethod
def pre_traversal(root, visit_func):
'''
@brief 先序遍历
@param root 当前访问的结点
@param visit_func 访问结点的函数
'''
if root is None:
return
visit_func(root)
tree_node.pre_traversal(root.left, visit_func)
tree_node.pre_traversal(root.right, visit_func)
非递归版本:
@staticmethod
def pre_traversal_no(root, visit_func):
'''
@brief 先序遍历非递归
@param root 当前访问的结点
@param visit_func 访问结点的函数
'''
stk = stack.stack()
index = root
while index is not None and not stk.empty():
while index is not None:
visit_func(index)
stk.push(index)
index = index.left
if not stk.empty():
index = stk.top()
stk.pop()
index = index.right
1.2 中序遍历
先遍历左子结点,再遍历父结点,最后遍历右子结点。上述遍历顺序为:1 2 3 5 6 7 8
递归版本:
@staticmethod
def in_traversal(root, visit_func):
'''
@brief 中序遍历递归版本
@param root 当前访问的结点
@param visit_func 访问结点的函数
'''
if root is None:
return
tree_node.in_traversal(root.left, visit_func);
visit_func(root)
tree_node.in_traversal(root.left, visit_func);
非递归版本:
@staticmethod
def in_traversal_no(root, visit_func):
'''
@brief 中序遍历非递归版本
@param root 当前访问的结点
@param visit_func 访问结点的函数
'''
stk = stack.stack()
index = root
while not stk.empty() or index is not None:
while index is not None:
stk.push(index)
index = index.left
index = stk.top()
visit_func(index)
stk.pop()
index = index.right
1.3 后序遍历
后序遍历先遍历左子结点,再遍历右子结点最后遍历父结点。上述树的遍历顺序为:1 3 2 6 8 7 5
递归版本:
@staticmethod
def post_traversal(root, visit_func):
'''
@brief 后序遍历
@param root 当前访问的结点
@param visit_func 访问结点的函数
'''
if root is not None:
return
tree_node.post_traversal(root->left, visit_func)
tree_node.post_traversal(root->right, visit_func)
visit_func(root)
非递归版本:
@staticmethod
def post_traversal_no(root, visit_func):
'''
@brief 后序遍历非递归
@param root 当前访问的结点
@param visit_func 访问结点的函数
'''
rst = stack.stack()
snd = stack.stack()
while root is not None or not rst.empty():
while root is not None:
rst.push(root)
snd.push(root)
root = root.right
if not rst.empty():
root = rst.top()
rst.pop()
root = root.left
while not snd.empty():
root = snd.top();
snd.pop()
visit_func(root)
#第二个版本
@staticmethod
def post_traversal_no_II(root, visit_func):
'''
@brief 后序遍历非递归
@param root 当前访问的结点
@param visit_func 访问结点的函数
'''
if root is None:
return
stk = stack.stack()
pre = None
cur = None
stk.push(root)
while not stk.empty():
cur = stk.top()
if pre is None or pre.left == cur or pre.right == cur:
if cur.left is not None:
stk.push(cur.left)
elif cur.right is not None:
stk.push(cur.right)
elif cur.left == pre:
if cur.right is not None:
stk.push(cur.right)
else:
visit_func(cur)
stk.pop()
pre = cur
2.4 层序遍历
层序遍历是按照层次遍历,上述树的遍历顺序为:5 2 7 1 3 6 8
@staticmethod
def traverse_level(root, func):
'''
@brief 层序遍历
@param root 根节点
@param func 访问函数 func(node)
'''
q = queue.queue()
q.enqueue(root)
while not q.empty():
root = q.dequeue()
func(root)
if root.left is not None:
q.enqueue(root.left)
if root.right is not None:
q.enqueue(root.right)
2 二叉树的线索化
线索化是为每个结点添加两个格外信息一个前驱结点,即遍历过程中前一个结点和后继结点,即遍历过程中下一个结点。如下图为先序线索化,先序遍历顺序为:5 2 1 3 7 6 8
2.1 先序线索化
递归版本:
@staticmethod
def pre_threading(root, pre):
'''
@brief 前序线索化
'''
if root is None:
return
else:
pre.next = root
root.pre = pre
pre = root
thread_tree_node.pre_threading(root.left , pre)
thread_tree_node.pre_threading(root.right, pre)
非递归版本:
@staticmethod
def pre_threading_no(root):
'''
@brief 先序线索化
'''
if root is not None:
return
else:
pre = None
stk = stack.stack()
index = root
while index is not None and not stk.empty():
while index is not None:
if pre is not None:
pre.next = root
root.pre = pre
stk.push(index)
index = index.left
if not stk.empty():
index = stk.top()
stk.pop()
index = index.right
2.2 中序线索化
递归版本:
@staticmethod
def in_threading(root, pre):
'''
@brief 中序线索化
'''
if root is None:
return
else:
thread_tree_node.in_threading(root.left, pre)
if pre is not None:
pre.next = root
root.pre = pre
pre = root
thread_tree_node.in_threading(root.right, pre)
非递归版本:
@staticmethod
def in_threading_no(root):
'''
@brief 中序线索化非递归版本
'''
if root is None:
reutrn
else:
stk = stack.stack()
index = root
pre = None
while not stk.empty() or index is not None:
while index is not None:
stk.push(index)
index = index.left
index = index.top()
stk.pop()
index.pre = pre
if pre is not None:
pre.next = index
index = index.right
2.3 后序线索化
递归版本:
@staticmethod
def post_threading(root, pre):
'''
@brief 后序线索化
'''
if root is None:
return
else:
thread_tree_node.post_threading(root.left, pre)
thread_tree_node.post_threading(root.right, pre)
pre.next = root
root.pre = pre
pre = root
非递归版本:
@staticmethod
def post_threading_no(root, visit_func):
'''
@brief 后序遍历非递归
@param root 当前访问的结点
@param visit_func 访问结点的函数
'''
rst = stack.stack()
snd = stack.stack()
while root is not None or not rst.empty():
while root is not None:
rst.push(root)
snd.push(root)
root = root.right
if not rst.empty():
root = rst.top()
rst.pop()
root = root.left
pre = None
while not snd.empty():
root = snd.top();
if pre is not None:
pre.next = root
root.pre = pre
snd.pop()
visit_func(root)