这里写自定义目录标题
1. 题目
给你二叉树的根节点 root
,返回它节点值的 前序 遍历。
1.1 示例
-
示例 1 1 1:
- 输入:
root = [1, null, 2, 3]
- 输出:
[1, 2, 3]
- 输入:
-
示例 2 2 2:
- 输入:
root = []
- 输出:
[]
- 输入:
1.2 说明
- 来源: 力扣(LeetCode)
- 链接: https://leetcode-cn.com/problems/binary-tree-preorder-traversal
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 遍历。