Python 二叉树遍历方式总结
二叉树节点定义
class Node():
def __init__(self, val):
self.val = val
self.left = None
self.right = None
递归遍历
递归实现前中后序遍历
class Traverse():
def preorder_traverse(self, root):
if root is None: return None
print(root.val, end=' ')
self.preorder_traverse(root.left)
self.preorder_traverse(root.right)
def inorder_traverse(self, root):
if root is None: return None
self.inorder_traverse(root.left)
print(root.val, end=' ')
self.inorder_traverse(root.right)
def postorder_traverse(self, root):
if root is None: return None
self.postorder_traverse(root.left)
self.postorder_traverse(root.right)
print(root.val, end=' ')
非递归遍历
前序遍历
- 压栈过程:首先压入根节点,对于
pop
出的节点,先压入其孩子,再压入左孩子(如果存在) - 出栈过程:
pop
栈顶节点,然后执行压栈过程
def preorder_traverse_with_stack(self, root):
if root is None: return None
stack = []
stack.append(root)
while stack:
node = stack.pop()
print(node.val, end=' ')
if node.right: stack.append(node.right)
if node.left: stack.append(node.left)
print('')
中序遍历
- 压栈过程:第一次访问到该节点压栈,然后再去找该节点的左孩子压栈;
- 出栈过程:当前无节点可压栈(已经到了最左的叶子节点),
pop
一个节点并打印,如果pop
的节点有右孩子,那么重复压栈过程。
def inorder_traverse_with_stack(self, root):
if root is None: return None
stack = []
while stack or root:
if root:
stack.append(root)
root = root.left
else:
root = stack.pop()
print(root.val, end=' ')
root = root.right
print('')
后续遍历
def post_traverse_with_one_stack(self, root):
if root is None: return None
stack = []
while stack or root:
while root:
if root.right:
stack.append(root.right)
stack.append(root)
root = root.left
node = stack.pop()
if stack and node.right and node.right == stack[-1]:
root = stack.pop()
stack.append(node)
else:
print(node.val, end=' ')
root = None
print('')
Morris 遍历
对于当前节点cur:
- 如果cur节点没有左子树,cur指向cur的右孩子;
- 如果cur节点有左子树:
- 如果是第一次到达cur节点,即cur节点的左子树的最右节点的右孩子指向空,那么将该最右节点的右孩子设置为节点cur,cur 指向cur的左孩子
- 如果是第二次到达cur节点,即cur节点的左子树的最右节点的右孩子指向cur节点,那么将该最右节点的右孩子还原为空,cur 指向cur的右孩子
class MorrisTraverse():
def morris_traverse(self, root):
if root is None: return None
cur, most_right = root, None
while cur:
most_right = cur.left
if most_right:
while most_right.right and most_right.right != cur:
most_right = most_right.right
if most_right.right is None:
most_right.right, cur = cur, cur.left
continue
else:
most_right.right = None
cur = cur.right