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

posted on 2022-07-01 13:35  solvit  阅读(109)  评论(0编辑  收藏  举报

导航