• 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
    
  • 相关阅读:
    【gtest/gmock】警告与报错集合
    【gtest/gmock】gmock:Mock的常用方法
    【C++容器】vector 和 list 的区别
    【C++百科】C++标准库到底是什么?
    【C++】设置、改变、获取系统环境变量:setenv & putenv & getenv
    【C++调试】error: 编译报错合集
    【C++调试】 warning: 编译警告合集
    Linux常用命令
    tcpdump及wireshark组合使用
    Vim快捷键
  • 原文地址:https://www.cnblogs.com/solvit/p/16434358.html
Copyright © 2020-2023  润新知