zoukankan      html  css  js  c++  java
  • 二叉树的前中后序遍历

    二叉树的前序、中序、后续遍历
    
    前序、中序、后序指的是根输出的顺序
    1.递归遍历
    前序遍历:打印 -> 左 -> 右
    中序遍历:左 -> 打印 -> 右
    后序遍历:左 -> 右 -> 打印
    
    1.1递归前序遍历
    from typing import List
    class Solution:
        def preorderTraversal(self, root: TreeNode) -> List[int]:
            path = []
            def dfs(tree_node):
                if not tree_node:
                    return
                path.append(tree_node.val)
                dfs(tree_node.left)
                dfs(tree_node.right)
    
            dfs(root)
            return path
    
    1.2递归中序遍历
    终止条件:当前节点为空
    函数内:递归的调用左节点,打印当前节点,再递归调用右节点
    时间复杂度:O(n)
    空间复杂度:O(h),h是树的高度
    
    from typing import List
    class Solution:
        def inorderTraversal(self, root: TreeNode) -> List[int]:
            path = []
            def dfs(tree_node):
                if not tree_node:
                    return
                dfs(tree_node.left)
                path.append(tree_node.val)
                dfs(tree_node.right)
    
            dfs(root)
            return path
    
    1.3递归后序遍历
    
    from typing import List
    class Solution:
        def postorderTraversal(self, root: TreeNode) -> List[int]:
            path = []
            def dfs(tree_node):
                if not tree_node:
                    return
                dfs(tree_node.left)
                dfs(tree_node.right)
                path.append(tree_node.val)
    
            dfs(root)
            return path
    
    
    2. 栈 + 迭代
    
    递归实现时,是函数自己调用自己,一层层的嵌套下去,操作系统/虚拟机自动帮我们用栈来保存了每个调用的函数,现在我们需要自己模拟这样的调用过程
    #栈 ,先进后出
    # 前序遍历,出栈顺序:根左右
    # 中序遍历,出栈顺序:左根右
    # 后序遍历,出栈顺序:左右根
    
    2.1迭代前序遍历
    
    2.1.1模拟递归迭代过程的编码方式
    
    from typing import List
    class Solution:
        def preorderTraversal(self, root: TreeNode) -> List[int]:
            ans = []
            stack = []
            while stack or root:
                if root:
                    ans.append(root.val)
                    stack.append(root)
                    root = root.left
                else:
                    tmp = stack.pop()
                    root = tmp.right
            return ans
    
    2.1.2 利用进出栈顺序编程
    
    前序遍历顺序:  中左右
    用列表模拟栈: 栈 ->后进先出
    故前序遍历     出栈顺序:中左右 入栈顺序:右左中
    
    class Solution:
        def preorderTraversal(self, root: TreeNode) -> List[int]:
            ans = []
            stack = []
            if not root:
                return ans
            stack.append(root)
            while stack:
                tree_node = stack.pop()
            #入栈顺序右左中
                ans.append(tree_node.val)
                if tree_node.right:
                    stack.append(tree_node.right)
                if tree_node.left:
                    stack.append(tree_node.left)
            return ans
    
    #更好理解的前序迭代
    class Solution:
        def inorderTraversal(self, root: TreeNode) -> List[int]:
            #列表模拟栈 ,先进后出
            #前序、中序、后序指的是根输出的顺序
            # 前序遍历,出栈顺序:根左右,入栈顺序:右左根
            ans = []
            stack = []
            if root:
                stack.append(root)
            while stack:
                node = stack.pop()
                if node:
                    if node.right:#
                        stack.append(node.right)
                    if node.left:#
                        stack.append(node.left)
                    stack.append(node)#
                    stack.append(None)
                else:
                    node = stack.pop()
                    ans.append(node.val)
            return ans
    
    
    
    2.2 迭代中序遍历
    
    2.2.1 模拟递归迭代过程
    class Solution:
        def inorderTraversal(self, root: TreeNode) -> List[int]:
            
            ans = []
            stack = []
            while stack or root:
                # 不断往左子树方向前进,每次前进将当前节点保存到栈中
                # 模拟递归的调用
                if root:
                    stack.append(root)
                    root = root.left
                #当前节点为空时,说明左边走到头,从栈中弹出节点并保存
                #然后转到右边节点,继续上面的过程
                else:
                    tmp = stack.pop()
                    ans.append(tmp.val)
                    root = tmp.right
            return ans
    
    更好理解的中序迭代
    class Solution:
        def inorderTraversal(self, root: TreeNode) -> List[int]:
            # 中序遍历,出栈顺序:左根右,入栈顺序:右根左
            ans = []
            stack = []
            if root:
                stack.append(root)
            while stack:
                node = stack.pop()
                if node:
                    if node.right:#
                        stack.append(node.right)
                    stack.append(node)#
                    stack.append(None)#中节点访问过,但未处理,加入空节点做标记
                    if node.left:#
                        stack.append(node.left)
                else:
                    node = stack.pop()
                    ans.append(node.val)
            return ans
    
    2.3 迭代后序遍历
       
    from collections import deque
    from typing import List
    
    
    class TreeNode:
        def __init__(self, val=0, left=None, right=None):
            self.val = val
            self.left = left
            self.right = right
    
    
    def make_tree(data):
        if data == []:
            return
        root = TreeNode(data[0])
        queue = deque([root])
        i = 1
        while i < len(data):
            node = queue.popleft()
            if data[i] != 'null':
                node.left = TreeNode(data[i])
                queue.append(node.left)
            i = i + 1
            if data[i] != 'null':
                node.right = TreeNode(data[i])
                queue.append(node.right)
            i = i + 1
        return root
    
    
    class Solution:
        def postorderTraversal(self, root: TreeNode) -> List[int]:
        # 后序遍历,出栈顺序:左右根,入栈顺序:根右左
            ans = []
            stack = []
            if root:
                stack.append(root)
            while stack:
                node = stack.pop()
                if node:
                    stack.append(node)#中节点访问过,但未处理,加入空节点做标记
                    stack.append(None)
                    if node.right:
                        stack.append(node.right)#
                    if node.left:
                        stack.append(node.left)#
                else:
                    node = stack.pop()
                    ans.append(node.val)
            return ans
    View Code
  • 相关阅读:
    [luogu p1996] 约瑟夫问题
    [luogu p1098] 字符串的展开
    [luogu p1035] 级数求和
    [luogu p1004] 方格取数
    [luogu p3383]【模板】线性筛素数
    [luogu p1223] 排队接水
    [luogu p1002] 过河卒
    [luogu p1001] A+B Problem
    Java BIO/NIO(Non-blocking I/O)详解
    Linux页框&伙伴算法以及slab机制
  • 原文地址:https://www.cnblogs.com/wuxunyan/p/15069914.html
Copyright © 2011-2022 走看看