当前位置: 首页 > 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.gsyq.cn/news/14569.html

相关文章:

  • 2025 年冷却塔品牌最新推荐排行榜:玻璃钢冷却塔、闭式冷却塔、方型逆流式冷却塔优质厂家 TOP3 精选,赋能企业选购
  • 微服务调整中心高可用设计:从踩坑到落地的实战指南(二)
  • NOIP2025模拟赛30
  • copyparty.exe 怎么用?局域网文件共享工具安装与运行教程
  • 2025西安高端新房,西安优质新房,西安品牌新房住宅推荐,地建嘉信臻境,沣东文商板块门户,享双地铁便利
  • STM32 智能垃圾桶项目笔记(二):超声波测距功能实现 - 指南
  • 通过配置 GitLab 自动触发项目自动化构建与部署 - 指南
  • 详细介绍:MySQL备份策略核心知识点总结
  • 2025年陕西品牌楼盘,西安城西优质楼盘,西咸新区核心楼盘住宅口碑推荐,地建嘉信臻境距吾悦广场一路之隔,商业配套完善
  • 完整教程:跨会话泄露:AI时代下的安全挑战与防御策略
  • 详细介绍:Nginx 访问控制、用户认证与 HTTPS 配置指南
  • 前端-JavaScript简介JavaScript模块化 - 努力-
  • VisualMimic——基于视觉的人形行走-操作控制:低层策略负责平衡控制且跟踪高层下发的指令、高层策略则基于自我中心视觉输入生成任务跟踪指令 - 实践
  • 详细介绍:SQL 执行异常排查 java.sql.SQLException:从 SQLException 说起
  • AI 真能胜任专业工程师的工作吗?
  • OpenWRT中备份多个docker容器的脚本 -
  • (附源码)基于Spring Boot的宿舍管理系统设计与建立0007
  • 一文掌握 Apache SeaTunnel 构建优秀的系统与分发基础架构
  • 详细介绍:Oracle与Kingbase深度兼容体验:从连接配置到性能优化全解析
  • [LeetCode] 1518. Water Bottles
  • 题解:P14073 [GESP202509 五级] 数字选取
  • 张雪峰的事儿,大有文章
  • 技术内容思路构建Promot
  • # SICP学习笔记:计算机程序的构造与解释
  • 2025包装机厂家推荐榜单出炉:拉伸膜真空包装机,全自动真空包装机,滚动式真空包装机,食品真空包装机,气调包装机公司推荐!
  • 【半导体器件 | 笔记】金属氧化物半导体场效应晶体管(MOSFET)
  • 元人文AI场域:在有限与无限的纠缠中走向智慧文明
  • 【半导体器件 | 笔记】pn结二极管
  • Day2:Linux文件目录移到拷贝与vim编辑器使用指南
  • 【半导体物理 | 笔记】第八章 半导体表面与MIS结构