树的统一迭代法

news/2025/10/1 13:54:09/文章来源:https://www.cnblogs.com/jiangbyte/p/19122403

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

树的递归遍历

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

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.mzph.cn/news/923905.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么seo网站排名wordpress搭建电影

1、自己准备训练语料文件 根据自己的业务场景准备训练数据&#xff0c;比如用户在商城上的同购行为序列或同浏览行为序列。 我们希望通过自己训练业务相关的语料word2vec模型来获得词嵌入、词相关性查询等。 1.1 准备语料库文件 # 示例&#xff1a;准备自己的一个大规模的语…

集团网站开发费用关键词优化的价格查询

1. 题目 给你一个 n 行 m 列的二维网格 grid 和一个整数 k。你需要将 grid 迁移 k 次。 每次「迁移」操作将会引发下述活动&#xff1a; 位于 grid[i][j] 的元素将会移动到 grid[i][j 1]。 位于 grid[i][m - 1] 的元素将会移动到 grid[i 1][0]。 位于 grid[n - 1][m - 1] …

asp网站源码+access+机械移动网站开发技术有哪些

实验项目&#xff1a;RSA公钥加密与签名实验 1.实验目的 本实验的学习目标是让学生获得 RSA 算法的动手经验。 通过课堂学习&#xff0c;学生应该已经了解 RSA 算法的理论部分&#xff0c; 知道在数学上如何生成公钥、私钥以及如何执行加密、解密和签名生成、验证。 通过使用…

深入解析:4-6〔O҉S҉C҉P҉ ◈ 研记〕❘ WEB应用攻击▸文件上传漏洞-A

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025 年冷却塔品牌最新推荐排行榜:玻璃钢冷却塔、闭式冷却塔、方型逆流式冷却塔优质厂家 TOP3 精选,赋能企业选购

随着工业生产与建筑行业的快速发展,冷却塔作为关键散热设备,市场需求日益攀升。但当前市场上冷却塔品牌数量众多,产品质量与性能参差不齐,从散热效率到节能效果,从材质耐用性到售后服务,差异显著。许多企业在选购…

详细介绍:基于Chrome140的FB账号自动化——脚本撰写(二)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

CentOS7二进制安装包方式部署K8S集群之CA根证书生成 - 实践

CentOS7二进制安装包方式部署K8S集群之CA根证书生成 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consol…

网站地址栏做1个响应式设计网站好

全世界只有3.14 % 的人关注了爆炸吧知如何才能学好数学&#xff1f;我国著名数学家苏步青先生曾说&#xff1a;"要学好数学&#xff0c;方法不外乎打好基础&#xff0c;多做习题&#xff0c;多加思索和分析”。为了帮助大家学好数学&#xff0c;今天&#xff0c;超模君要给…

旅游网站开发系统的er图网站建设 公司 广州

1.android电池充满电剩余时间 android电量还需多长时间充满时间计算参考下面链接: [Android Framework] 8.1 Battery系列(四) 电量还需多长时间充满时间计算_batteryinfo.java-CSDN博客 从这个链接中可以看出android默认的计算方式为平均计算每1%所需要的时间,在乘以剩余的电…

旅游景区网站源码长沙网络科技有限公司有哪些

介绍 赋值运算符就是将某个运算后的值&#xff0c; 赋给指定的变量。 赋值运算符的分类 基本赋值运算符 例如&#xff1a; int a 10; 复合赋值运算符 &#xff0c; - &#xff0c; * &#xff0c; / &#xff0c; % 等 a b; [等价 a a b; ] a - b; [等价 a a - b; ] …

可以做进销存的网站系统百度网站改版工具

QQ的庞大安装量带动了腾讯系的所有产品的安装量&#xff0c;QQ浏览器作为腾讯旗下开发的浏览工具&#xff0c;也拥有不俗的装机量。QQ浏览器不仅是沾了QQ的光&#xff0c;其自身实力也有不俗的&#xff0c;QQ浏览器的应用中心与其他浏览器的扩展中心一般支持用户安装各种浏览器…

软件设计师——03 数据结构(上) - 详解

软件设计师——03 数据结构(上) - 详解2025-10-01 13:31 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block…

深圳网站建设公司地图建站官网模板

给自己一个目标&#xff0c;然后坚持一段时间&#xff0c;总会有收获和感悟&#xff01; 在实际项目开发中&#xff0c;多少都会遇到高并发的情况&#xff0c;有可能是网络问题&#xff0c;连续点击鼠标无反应快速发起了N多次调用接口&#xff0c; 导致极短时间内重复调用了多次…

DailyPaper-2025-9-30

感觉今天 paper 质量不是很高, 刚考完试太累了也读不很下去. SLA: Beyond Sparsity in Diffusion Transformers via Fine-Tunable Sparse-Linear Attention https://arxiv.org/abs/2509.24006SLA, a trainable attenti…

Powershell 管理 后台/计划 作业(六)

Powershell 管理 后台/计划 作业目录管理 后台/计划 作业后台作业本地作业远程作业CIM / WMI 作业作业的管理检索作业查看子作业简单案例计划作业作业选项作业触发器创建和注册使用流程查看与管理与任务计划程序的关系…

【stm32】bash自动配置buildenv - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

java17及以上版本如何抵御TemplatesImpl注入

最近有一篇写的很好的关于java17反序列化绕过模块化的文章:https://mp.weixin.qq.com/s/DrUUAJaLig_RtXZWaAm1IQ 关于本篇的方式方法也比较传统,直接jep290在java运行时增加命令行参数: -Djdk.serialFilter=!com.su…

详细介绍:【C++实战(53)】C++11线程库:开启多线程编程新世界

详细介绍:【C++实战(53)】C++11线程库:开启多线程编程新世界pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Con…

wordpress让小工具支持简码汕头百度seo在哪里

2006-2023年各地级市债务余额数据 1、时间&#xff1a;2006-2023年 2、来源&#xff1a;整理自wind 3、指标&#xff1a;地区、地方政府债-债券数量(只)、地方政府债-债券余额(亿)、地方政府债-债券余额占比(%)、城投债-债券数量(只)、城投债-债券余额(亿)、城投债-债券余额…

将图片某个区域批量填充白色(jsx代码)

// 定义源文件夹和目标文件夹路径 var sourceFolderPath = "C:/Users/***/Desktop/拆分/"; var destFolderPath = "C:/Users/***/Desktop/结果/";// 定义要填充的区域坐标 (x, y, 宽度, 高度) var…