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

树的统一迭代法

树的统一迭代法是一种比较通用的遍历方法,通过标记法来实现前序、中序、后序遍历,核心思想是通过栈中加入空指针来标记访问节点和处理节点的时机

树的递归遍历

递归遍历比较简单,只要完成模板,更改添加元素的位置代码,就可以轻松实现遍历顺序的调整

class Solution {public List<Integer> treeTraversal(TreeNode root) {// 创建结果列表,用于存储遍历结果List<Integer> result = new ArrayList<>();// 调用递归遍历方法,从根节点开始遍历traversal(root, result);// 返回完整的遍历结果return result;}/*** 递归遍历二叉树的核心方法* 通过调整三行代码的顺序,可以实现前序、中序、后序遍历* * @param root 当前遍历的节点* @param result 存储遍历结果的列表*/public void traversal(TreeNode root, List<Integer> result) {// 递归终止条件:当前节点为空,直接返回if (root == null) {return;}// ========== 前序遍历:中 -> 左 -> 右 ==========// 先访问当前节点(中)result.add(root.val); // 递归遍历左子树(左)traversal(root.left, result);// 递归遍历右子树(右)traversal(root.right, result);}
}

三种遍历的对比

前序遍历(中左右)

result.add(root.val);        // 中
traversal(root.left, result);  // 左
traversal(root.right, result); // 右

中序遍历(左中右)

traversal(root.left, result);  // 左
result.add(root.val);        // 中
traversal(root.right, result); // 右

后序遍历(左右中)

traversal(root.left, result);  // 左
traversal(root.right, result); // 右
result.add(root.val);        // 中

复杂度分析

时间复杂度 O(n)

  • n 二叉树中的节点总数
  • 每个节点只被访问一次:递归函数对每个节点恰好调用一次
  • 常数时间操作:每个节点的处理(result.add())是 O(1) 操作
  • 总时间复杂度:n 个节点 × O(1) = O(n)

空间复杂度 O(h)

  • h 二叉树的高度
  • 递归调用栈的空间
    • 最坏情况:当树退化为链表时,h = n,空间复杂度为 O(n)
    • 最好情况:当树是平衡二叉树时,\(h = log_2{n}\),空间复杂度为 O(log n)
    • 平均情况:O(h),其中 h 是树的高度

树的统一迭代法

  • 普通节点:需要遍历的节点
  • 空节点:作为标记,表示下一个节点应该被处理加入结果集
public List<Integer> treeTraversal(TreeNode root) {// 创建结果列表,用于存储遍历结果List<Integer> result = new ArrayList<>();// 创建栈,用于模拟递归调用栈Stack<TreeNode> st = new Stack<>();// 如果根节点不为空,将其压入栈中开始遍历if (root != null) {st.push(root);}// 循环遍历直到栈为空while (!st.isEmpty()) {// 查看栈顶元素,但不弹出(peek操作)TreeNode node = st.peek();if (node != null) {// ========== 访问阶段 ==========// 当前节点不为空,说明是待访问的节点// 弹出当前节点,为重新组织访问顺序做准备st.pop();// ========== 前序遍历访问顺序:右 -> 左 -> 中 ==========// 栈是LIFO(后进先出),所以入栈顺序与遍历顺序相反// 如果右子节点不为空,将右子节点压入栈中if (node.right != null) {st.push(node.right); // 右子节点}// 如果左子节点不为空,将左子节点压入栈中if (node.left != null) {st.push(node.left);  // 左子节点}// 将当前节点重新压入栈中st.push(node);           // 当前节点(中)// 压入空节点作为标记,表示这个节点已经被访问过但还没有被处理// 当后续遇到这个空标记时,就知道下一个节点应该被处理(加入结果集)st.push(null);           // 空标记} else {// ========== 处理阶段 ==========// 当前节点为空,说明遇到了之前设置的空标记// 空标记的下一个节点就是应该被处理的节点// 弹出空标记节点(当前栈顶的null)st.pop();// 查看栈顶元素(真正要处理的节点)node = st.peek();// 弹出要处理的节点st.pop();// 将节点的值加入结果列表,就是"处理"节点的操作result.add(node.val);}}// 返回遍历结果return result;
}

三种遍历的对比

前序遍历(中左右)

// 访问顺序:右 -> 左 -> 中
if (node != null) {st.pop();if (node.right != null) st.push(node.right);  // 右if (node.left != null) st.push(node.left);    // 左  st.push(node);                              // 中st.push(null);
}

中序遍历(左中右)

// 访问顺序:右 -> 中 -> 左
if (node != null) {st.pop();if (node.right != null) st.push(node.right);  // 右st.push(node);                              // 中st.push(null);if (node.left != null) st.push(node.left);    // 左
}

后序遍历(左右中)

// 访问顺序:中 -> 右 -> 左
if (node != null) {st.pop();st.push(node);                              // 中st.push(null);if (node.right != null) st.push(node.right);  // 右if (node.left != null) st.push(node.left);    // 左
}

复杂度分析

时间复杂度 O(n)

  • n 二叉树中的节点总数
  • 每个节点被处理两次:每个节点经历一次"访问阶段"(入栈和标记)和一次"处理阶段"(加入结果集)
  • 常数时间操作:每个栈操作(push/pop/peek)和列表添加操作都是 O(1)
  • 总时间复杂度:n 个节点 × 常数次操作 = O(n)

空间复杂值 O(n)

  • 栈的空间使用
    • 最坏情况:当树退化为链表时,栈中同时存储约 2n 个元素(节点和空标记),空间复杂度为 O(n)
    • 最好情况:当树是平衡二叉树时,栈的最大深度约为 \(2 \times log_2{n}\),空间复杂度为 O(log n)
    • 平均情况:O(h),其中 h 是树的高度
  • 结果列表的空间:必须存储所有 n 个节点的值,空间复杂度为 O(n)
  • 总空间复杂度:栈空间 O(h) + 结果列表 O(n) = O(n)
http://www.hskmm.com/?act=detail&tid=22253

相关文章:

  • 2025 年冷却塔品牌最新推荐排行榜:玻璃钢冷却塔、闭式冷却塔、方型逆流式冷却塔优质厂家 TOP3 精选,赋能企业选购
  • DailyPaper-2025-9-30
  • Powershell 管理 后台/计划 作业(六)
  • 32. 最长有效括号
  • java17及以上版本如何抵御TemplatesImpl注入
  • 详细介绍:【C++实战(53)】C++11线程库:开启多线程编程新世界
  • 将图片某个区域批量填充白色(jsx代码)
  • 《初等数论(第四版,北京大学出版社,潘承洞,潘承彪著)》阅读笔记+心得
  • 完整教程:Word和WPS文字中的自动编号和文字间距过大怎么办?
  • markdown笔记文件批量打上时间戳
  • 251001
  • 微服务调整中心高可用设计:从踩坑到落地的实战指南(二)
  • NOIP2025模拟赛27
  • NOIP2025模拟赛28
  • 十月数据结构题没做
  • NOIP2025模拟赛30
  • 2025西安品牌新房,西安刚需新房,陕西优质新房住宅推荐,地建嘉信臻境,超2000㎡高端会所,满足多元化生活需求
  • 2025年未央区高端楼盘,西咸新区品质楼盘,西安高新品牌楼盘住宅口碑推荐,地建嘉信臻境周边配套丰富,教育医疗商业齐全
  • 2025西安高端新房,西安优质新房,西安品牌新房住宅推荐,地建嘉信臻境,沣东文商板块门户,享双地铁便利
  • 2025年西安洋房楼盘,陕西优质楼盘,西咸新区现房楼盘住宅口碑推荐,地建嘉信臻境超2000㎡高端会所,功能多样
  • Python 闭包的应用场景与实战案例
  • input() 函数
  • 如何确保CMS系统能够飞快响应用户请求?全面性能优化指南
  • 近期
  • Playwright MCP 的使用与调试技巧
  • 实用指南:零基础学AI大模型之LangChain-PromptTemplate
  • 文件上传攻击全面指南:从侦察到防御
  • 2025年陕西洋房楼盘,西安城西品质楼盘,沣东品牌楼盘住宅口碑推荐,地建嘉信臻境户型多元布局,满足全周期生活需求
  • asus nuc15 pro ultra7 255H 外接 fevm 雷电5显卡坞 BIOS设置
  • P11529 [THUPC 2025 初赛] 辞甲猾扎