【LeetCode 二叉树专项】二叉树的前序遍历(144)

1. 题目

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

1.1 示例

  • 示例 1 1 1

    • 输入: root = [1, null, 2, 3]
    • 输出: [1, 2, 3]

在这里插入图片描述

  • 示例 2 2 2

    • 输入: root = []
    • 输出: []

1.2 说明

1.3 限制

  • 二叉树的结点数量在 [ 0 ,   100 ] [0,\textit{ }100] [0, 100]
  • -100 <= Node.val <= 100

1.4 进阶

递归算法很简单,你可以通过迭代算法完成吗?

2. 解法一(递归法)

2.1 分析

二叉树的前序遍历使用递归的方式很容易实现,即按照访问 根节点 -> 左子树 -> 右子树 的方式遍历这棵树,而在访问左子树或者右子树的时候,按照同样的方式遍历,直到遍历完整棵树。可以看出,整个遍历过程天然具有递归的性质,因此可以直接用递归函数来模拟这一过程。

2.2 解答

from typing import List


class TreeNode:
    def __init__(self, val=0, left: 'TreeNode' = None, right: 'TreeNode' = None):
        self.val = val
        self.left = left
        self.right = right


class Solution:
    def __init__(self):
        self.tree = []

    def _preorder(self, root: TreeNode):
        if not root:
            return
        self.tree.append(root.val)
        self._preorder(root.left)
        self._preorder(root.right)

    def preorder_traversal(self, root: TreeNode) -> List[int]:
        self._preorder(root)
        return self.tree

2.3 复杂度

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的节点数。每一个节点恰好被遍历一次。
  • 空间复杂度: O ( n ) O(n) O(n) ,为递归过程中递归栈的开销和实例属性 self.tree 所占用空间两者组成,其中前者平均情况下为 O ( log ⁡ n ) O(\log n) O(logn),最坏情况下树呈现链状,为 O ( n ) O(n) O(n)

3. 解法二(迭代法)

3.1 分析

实际上,迭代法的前序遍历也很简单,为了实现按照 根节点 -> 左子树 -> 右子树 的顺序来遍历二叉树,可以利用栈的先进后出的特点,因此在遍历了根结点之后,先要将右子结点入栈然后再将左子结点入栈,这样就可以保证在遍历了根结点之后,下一次出栈的会是左子结点及其子孙结点,最后才是右子结点及其子孙结点。

3.2 解答

from typing import List


class TreeNode:
    def __init__(self, val=0, left: 'TreeNode' = None, right: 'TreeNode' = None):
        self.val = val
        self.left = left
        self.right = right


class Solution:
    def __init__(self):
        self.tree = []

    def iterative_preorder(self, root: TreeNode) -> List[int]:
        tree = []
        if not root:
            return tree
        stack = [root]
        while stack:
            node = stack.pop()
            tree.append(node.val)
            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
        return tree

3.3 复杂度

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的节点数。每一个节点恰好被遍历一次。
  • 空间复杂度: O ( n ) O(n) O(n) ,为递归过程中显式栈的开销和实例属性 self.tree 所占用空间两者组成,其中前者平均情况下为 O ( log ⁡ n ) O(\log n) O(logn),最坏情况下树呈现链状,为 O ( n ) O(n) O(n)

4. 解法三(Morris 遍历)

有一种巧妙的方法可以在线性时间内,只占用常数空间来实现前序遍历。这种方法由 J. H. Morris 在 1979 年的论文「Traversing Binary Trees Simply and Cheaply」中首次提出,因此被称为 Morris 遍历

猜你喜欢

转载自blog.csdn.net/weixin_37780776/article/details/121153808