当前位置: 首页 > news >正文

LeetCode 144:二叉树的前序遍历 | 递归与迭代

LeetCode 144:二叉树的前序遍历 | 递归与迭代

一、题目详解

1.1 题目描述

LeetCode 144:二叉树的前序遍历(Binary Tree Preorder Traversal)

给定一个二叉树的根节点root,返回它的前序遍历结果。

难度:Medium

示例 1:

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

示例 2:

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

示例 3:

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

1.2 题目分析

前序遍历的顺序是:根节点 -> 左子树 -> 右子树

这是二叉树遍历的三种基本方式之一(前序、中序、后序),掌握这三种遍历方式是学习树结构的基础。


二、算法实现

2.1 递归实现

递归是最直观的实现方式,利用函数调用栈来模拟遍历过程:

def preorderTraversal(root): result = [] def traverse(node): if not node: return # 先访问根节点 result.append(node.val) # 递归遍历左子树 traverse(node.left) # 递归遍历右子树 traverse(node.right) traverse(root) return result

递归思路解析:

  1. 如果当前节点为空,直接返回
  2. 访问当前节点(将值加入结果列表)
  3. 递归处理左子树
  4. 递归处理右子树

2.2 迭代实现

使用显式栈来模拟递归调用:

def preorderTraversal_iterative(root): if not root: return [] result = [] stack = [root] while stack: node = stack.pop() result.append(node.val) # 注意:先压右子树,再压左子树 # 因为栈是后进先出,这样左子树会先被处理 if node.right: stack.append(node.right) if node.left: stack.append(node.left) return result

迭代思路解析:

  1. 初始化栈,将根节点入栈
  2. 弹出栈顶节点,访问它
  3. 将右子节点入栈(因为栈是LIFO,后处理)
  4. 将左子节点入栈(先处理)
  5. 重复直到栈为空

2.3 Morris遍历(O(1)空间复杂度)

这是一种不使用栈的遍历方法:

def preorderTraversal_morris(root): result = [] current = root while current: if not current.left: # 没有左子树,直接访问当前节点 result.append(current.val) current = current.right else: # 找到左子树的最右节点 predecessor = current.left while predecessor.right and predecessor.right != current: predecessor = predecessor.right if not predecessor.right: # 建立线索 predecessor.right = current result.append(current.val) current = current.left else: # 恢复树结构 predecessor.right = None current = current.right return result

三、复杂度分析

3.1 递归实现

  • 时间复杂度:O(n),每个节点访问一次
  • 空间复杂度:O(h),h为树的高度
    • 最好情况(平衡树):O(log n)
    • 最坏情况(链式树):O(n)

3.2 迭代实现

  • 时间复杂度:O(n),每个节点入栈出栈一次
  • 空间复杂度:O(h),栈的最大深度

3.3 Morris遍历

  • 时间复杂度:O(n),每个节点访问常数次
  • 空间复杂度:O(1),只使用常量额外空间

四、边界情况讨论

4.1 空树

root = None # 输出:[]

4.2 单节点树

root = TreeNode(1) # 输出:[1]

4.3 只有左子树

# 1 # / # 2 # / # 3 # 输出:[1, 2, 3]

4.4 只有右子树

# 1 # \ # 2 # \ # 3 # 输出:[1, 2, 3]

4.5 完全二叉树

# 1 # / \ # 2 3 # / \ / \ # 4 5 6 7 # 输出:[1, 2, 4, 5, 3, 6, 7]

五、实际应用场景

5.1 树的序列化

前序遍历常用于树的序列化操作:

def serialize(root): """将二叉树序列化为字符串""" result = [] def preorder(node): if not node: result.append("#") return result.append(str(node.val)) preorder(node.left) preorder(node.right) preorder(root) return ",".join(result)

5.2 表达式树求值

在前序表达式(波兰表达式)中,前序遍历可以用于求值:

# 表达式树: + # / \ # 3 * # / \ # 4 5 # 前序遍历:[+, 3, *, 4, 5] # 求值结果:3 + 4 * 5 = 23

5.3 文件系统遍历

在文件系统中,前序遍历对应深度优先搜索:

# 目录结构: # root/ # ├── docs/ # │ └── readme.txt # └── src/ # └── main.py # 前序遍历:[root, docs, readme.txt, src, main.py]

六、总结

6.1 核心要点

要点说明
遍历顺序根 → 左 → 右
递归实现简洁直观,容易理解
迭代实现使用栈模拟递归,适合处理大规模数据
Morris遍历O(1)空间复杂度,适合内存受限场景

6.2 与其他遍历的对比

遍历方式顺序特点
前序根→左→右适合复制树、序列化
中序左→根→右BST中得到有序序列
后序左→右→根适合释放资源、计算子树信息
层序按层访问适合求树的深度、宽度优先搜索

6.3 扩展思考

  1. 如何在前序遍历中记录节点的深度信息?
  2. 如何修改算法,同时输出节点的路径信息?
  3. 前序遍历在哪些算法问题中是关键步骤?

参考资料:

  • LeetCode 144 题解
  • 二叉树遍历总结
http://www.jsqmd.com/news/900681/

相关文章:

  • 2026年 东莞切削液厂家推荐榜单/半合成/全合成/不锈钢/模具钢/低泡/合金钢切削液品牌精选,长效冷却与防锈性能深度解析 - 品牌企业推荐师(官方)
  • 从怀旧游戏到Unity资源:我是如何把《寻秦OL》的动画文件“复活”的(逆向工程全记录)
  • 从‘ban.so’解密到签名校验:一次完整的外挂逆向分析与修复实录
  • 基于QT(C++)+Sqlite3实现单词消除游戏系统
  • 机械臂夹爪品牌选型要点:匹配多款机械臂设备搭载 - 品牌2025
  • 从UGUI Button到自定义事件:手把手教你用UnityEvent重构游戏中的消息系统(避免强引用内存泄漏)
  • Windows 10/11 安装方正仿宋GBK字体后Word不生效?教你正确关闭文档的姿势
  • 避障小车代码调试踩坑实录:HC-SR04测距不准、SG90舵机乱转?51单片机常见问题解决
  • 保姆级教程:用Docker Compose一键部署Jeecg-Boot微服务v3.4.2,告别环境配置烦恼
  • 从单片机裸奔到跑系统:ARM Cortex-M3的特权/用户模式与双堆栈如何守护你的FreeRTOS
  • 5000A温升大电流,稳当是头等大事
  • 上下料夹爪品牌实用选购经验:适配生产线进出料作业 - 品牌2025
  • 2026年5月更新:河北地区装饰冲孔板订购厂家深度解析与推荐 - 2026年企业资讯
  • 告别DLL依赖!手把手教你用MinGW静态链接libgcc、libstdc++和libwinpthread
  • Python实战:用AlphaBeta剪枝算法搞定井字棋AI(附完整代码)
  • 别再死记硬背了!用PTV Vissim 2024做交通仿真,这5个高效建模技巧让你事半功倍
  • 如何推导-cfd的误差和稳定性分析
  • 大家都在电脑上安装了openclaw了吗?
  • 2026年4月智慧泵房实力厂家哪家强,排污泵/潜水排污泵/一体化污水处理设备/供水控制柜,智慧泵房源头厂家哪个好 - 品牌推荐师
  • SAP EWM拣货队列配置避坑指南:从活动区域定义到RF手持端显示的完整流程
  • 别再死记公式了!用‘电脑价格猜猜看’和‘出门带伞’两件小事,5分钟掌握贝叶斯更新核心思想
  • route 命令设置路由
  • 别再手动对位了!PCB钢网开Mark点,新手焊接效率翻倍的秘密
  • 告别imgaug!用Roboflow给YOLOv8数据集做增强,5分钟搞定格式转换和扩增
  • 2026年 DTF膜/墨水/烫画膜/热熔粉/弹性墨水,离型膜/氟素/非硅/硅油/硅胶离型膜源头厂家推荐榜 - 品牌企业推荐师(官方)
  • Vue3项目实战:用vis-timeline解决时间轴中文显示与日期格式化难题
  • 实测避坑:哪些安卓手机更适合跑VINS-MONO?从华为到小米的IMU数据采集体验报告
  • ChatGPT定制饮食计划失效真相:3类高危输入词+4步合规性校验流程(卫健委膳食指南交叉验证版)
  • ArcGIS 10.4 在 Win11 的“新家”安家记:为用arcpy的你详解安装路径选择
  • SystemVerilog bind 的‘坑’与最佳实践:从多实例绑定到参数传递的避雷指南