问题概述
给定一个二叉树的根节点 root,返回它的中序遍历。
什么是中序遍历?
中序遍历是三种主要的树遍历方法之一。它按照以下顺序访问节点:左子树 → 根节点 → 右子树
步骤:
- 遍历左子树(递归)
- 访问根节点
- 遍历右子树(递归)
可视化示例:
树: 1
\
2
/
3
中序遍历: [1, 3, 2]
- 从 1 开始,向左(无)→ 处理 1
- 向右到 2,向左到 3 → 处理 3
- 回到 2 → 处理 2
关键特性:
对于二叉搜索树(BST),中序遍历产生有序的值(升序),因为所有左子节点 < 根节点 < 所有右子节点。
解法 1:递归
工作原理
使用递归自然地遵循中序遍历模式:
python
class Solution:
def inorderTraversal(self, root):
if not root:
return []
return (self.inorderTraversal(root.left) +
[root.val] +
self.inorderTraversal(root.right))
复杂度分析
- 时间复杂度: O(n) - 每个节点恰好访问一次
- 空间复杂度: O(h) - 递归栈深度等于树的高度(最坏情况 O(n) 对于倾斜树)
何时使用
- 直观 - 实现树遍历最自然的方式
- 易于理解和实现
- 适合学习递归
解法 2:迭代(使用栈)(推荐)
工作原理
使用显式栈来模拟递归调用栈:
python
class Solution:
def inorderTraversal(self, root):
result = []
stack = []
current = root
while current or stack:
# 到达最左侧节点
while current:
stack.append(current)
current = current.left
# 处理节点
current = stack.pop()
result.append(current.val)
# 移动到右子树
current = current.right
return result
复杂度分析
- 时间复杂度: O(n) - 每个节点恰好访问一次
- 空间复杂度: O(h) - 栈大小等于树的高度(最坏情况 O(n) 对于倾斜树)
何时使用
- 推荐 - 对遍历有更多控制
- 避免深度树的递归栈溢出
- 可以轻松修改为其他遍历顺序
对比
| 方法 | 时间 | 空间 | 最佳适用 |
|---|---|---|---|
| 递归 | O(n) | O(h) | 学习,直观实现 |
| 迭代 | O(n) | O(h) | 生产代码,深度树 |
总结
递归和迭代方法都实现了 O(n) 时间复杂度。使用栈的迭代方法在生产代码中通常更受欢迎,因为它避免了潜在的栈溢出问题,并提供了对遍历过程的更多控制。关键洞察是尽可能向左走,处理节点,然后移动到右子树。