二叉树迭代遍历(三种写法)

news/2025/3/5 7:10:50/

 写法一(各个步骤分离)

前序遍历

	class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();//迭代算法preorderStack(root, list);return list;}  //通过栈的先进后出特性,将root节点放到栈中,对二叉树从遍历	   public void preorderStack(TreeNode root, List<Integer> list){Deque<TreeNode> stack = new LinkedList<>();        while(root != null || stack.isEmpty()){//root不为null时,将root节点和左子树节点放到栈中while(root != null){//获取根节点数据list.add(root.val);//将root节点放入栈中stack.push(root);//处理root左子树节点root = root.left;}//root为null,获取栈中root节点root = stack.pop();//处理root右子树节点root = root.right;}}}

中序遍历

	class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();//迭代算法inorderStack(root, list);return list;}  //通过栈的先进后出特性,将root节点放到栈中,对二叉树从遍历	   public void inorderStack(TreeNode root, List<Integer> list){//定义一个栈用于存放二叉树Deque<TreeNode> stack = new LinkedList<>();        while(root != null || stack.isEmpty()){//root不为null时,将root节点和左子树节点放到栈中while(root != null){                    //将root节点放入栈中stack.push(root);//处理root左子树节点root = root.left;}//root为null,获取栈中root节点root = stack.pop();//获取根节点数据list.add(root.val);//处理root右子树节点root = root.right;}}}

后序遍历

	class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();//迭代算法postorderStack(root, list);return list;}  //通过栈的先进后出特性,将root节点放到栈中,对二叉树从遍历	   public void postorderStack(TreeNode root, List<Integer> list){//定义一个栈用于存放二叉树Deque<TreeNode> stack = new LinkedList<>(); //用于判断当前处理右子树与上次处理的二叉树是否相同,避免再处理一次TreeNode pre = null;       while(root != null || stack.isEmpty()){//root不为null时,将root节点和左子树节点放到栈中while(root != null){                    //将root节点放入栈中stack.push(root);//处理root左子树节点root = root.left;}//root为null,获取栈中root节点root = stack.pop();//右子树为null 或 右子树 与 上次处理的pre 子树相等 不需在处理一遍, 取root节点值if(root.right == null || root.right == pre){                    //获取根节点数据list.add(root.val);//将当前root节点赋值给pre 用于标记pre = root;//将root重置为null,再次出栈遍历处理root = null;}else{//右子树不为null时,需将右子树入栈处理stack.push(root);//处理root右子树节点root = root.right;}                }}}

 

 写法二

// 前序遍历顺序:中-左-右,入栈顺序:中-右-左
class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();if (root == null){return result;}Stack<TreeNode> stack = new Stack<>();stack.push(root);while (!stack.isEmpty()){TreeNode node = stack.pop();result.add(node.val);if (node.right != null){stack.push(node.right);}if (node.left != null){stack.push(node.left);}}return result;}
}// 中序遍历顺序: 左-中-右 入栈顺序: 左-右
class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();if (root == null){return result;}Stack<TreeNode> stack = new Stack<>();TreeNode cur = root;while (cur != null || !stack.isEmpty()){if (cur != null){stack.push(cur);cur = cur.left;}else{cur = stack.pop();result.add(cur.val);cur = cur.right;}}return result;}
}// 后序遍历顺序 左-右-中 入栈顺序:中-左-右 出栈顺序:中-右-左, 最后翻转结果
class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();if (root == null){return result;}Stack<TreeNode> stack = new Stack<>();stack.push(root);while (!stack.isEmpty()){TreeNode node = stack.pop();result.add(node.val);if (node.left != null){stack.push(node.left);}if (node.right != null){stack.push(node.right);}}Collections.reverse(result);return result;}
}

写法三(三种遍历统一格式)

迭代法前序遍历代码如下:class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> result = new LinkedList<>();Stack<TreeNode> st = new Stack<>();if (root != null) st.push(root);while (!st.empty()) {TreeNode node = st.peek();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); // 中节点访问过,但是还没有处理,加入空节点做为标记。} else { // 只有遇到空节点的时候,才将下一个节点放进结果集st.pop();           // 将空节点弹出node = st.peek();    // 重新取出栈中元素st.pop();result.add(node.val); // 加入到结果集}}return result;}
}
迭代法中序遍历代码如下:class Solution {
public List<Integer> inorderTraversal(TreeNode root) {List<Integer> result = new LinkedList<>();Stack<TreeNode> st = new Stack<>();if (root != null) st.push(root);while (!st.empty()) {TreeNode node = st.peek();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);    // 添加左节点(空节点不入栈)} else { // 只有遇到空节点的时候,才将下一个节点放进结果集st.pop();           // 将空节点弹出node = st.peek();    // 重新取出栈中元素st.pop();result.add(node.val); // 加入到结果集}}return result;
}
}
迭代法后序遍历代码如下:class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> result = new LinkedList<>();Stack<TreeNode> st = new Stack<>();if (root != null) st.push(root);while (!st.empty()) {TreeNode node = st.peek();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);    // 添加左节点(空节点不入栈)         } else { // 只有遇到空节点的时候,才将下一个节点放进结果集st.pop();           // 将空节点弹出node = st.peek();    // 重新取出栈中元素st.pop();result.add(node.val); // 加入到结果集}}return result;}
}


http://www.ppmy.cn/news/1576759.html

相关文章

使用阿里云 API 进行声音身份识别的方案

使用阿里云 API 进行声音身份识别的方案 阿里云提供 智能语音交互&#xff08;智能语音识别 ASR&#xff09; 和 声纹识别&#xff08;说话人识别&#xff09; 服务&#xff0c;你可以利用 阿里云智能语音 API 进行 说话人识别&#xff0c;实现客户身份验证。 方案概述 准备工…

通俗易懂的聚类算法之K均值详解

K 均值聚类算法&#xff08;K-Means Clustering&#xff09; 是一种常用的无监督学习算法&#xff0c;用于将数据集划分为 K 个簇&#xff08;Cluster&#xff09;。它的核心思想是通过迭代优化&#xff0c;将数据点分配到最近的簇中心&#xff0c;并更新簇中心&#xff0c;直到…

07 搜索(BFS和DFS)图的遍历

引用链接&#xff1a;https://blog.csdn.net/weixin_43955293/article/details/126445861深度优先搜索&#xff08;DFS&#xff09;和广度优先搜索&#xff08;BFS&#xff09;_深度优先搜索和广度优先搜索对比-CSDN博客 1、广度优先遍历&#xff08;BFS&#xff09; 1.1概念…

Cherno 游戏引擎笔记(91~111)

好久不见&#xff01; 个人库的地址&#xff1a;&#xff08;GitHub - JJJJJJJustin/Nut: The game_engine which learned from Cherno&#xff09;&#xff0c;可以看到我及时更新的结果。 -------------------------------Saving & Loading scene-----------------------…

嵌入式软件测试工具的“安全与效率悖论”破局之道

嵌入式软件测试工具的“安全与效率悖论”破局之道 ——从winAMS的技术底层看行业范式升级 一、行业困境&#xff1a;当“安全需求”撞上“交付速度” 2024年&#xff0c;全球嵌入式软件测试工具市场规模达52亿美元&#xff0c;但市场痛点并未因规模扩张而缓解‌&#xff1a; …

20250304笔记-阅读论文

文章目录 前言一、寻找论文1.1寻找有代码的论文方法一&#xff1a;浏览器扩展1.1.1使用流程 方法二&#xff1a;使用Papers with Code 1.2大量搜索代码 二、阅读论文所用软件 三、引用文献格式总结 前言 一、寻找论文 1.1寻找有代码的论文 方法一&#xff1a;浏览器扩展 浏览…

游戏引擎学习第120天

仓库:https://gitee.com/mrxiao_com/2d_game_3 上次回顾&#xff1a;周期计数代码 我们正在进行一个项目的代码优化工作&#xff0c;目标是提高性能。当前正在优化某个特定的代码片段&#xff0c;已经将其执行周期减少到48个周期。为了实现这一目标&#xff0c;我们设计了一个…

【大模型基础_毛玉仁】0.概述

更多内容&#xff1a;XiaoJ的知识星球 【大模型基础_毛玉仁】 系列文章参考 系列文章 【大模型基础_毛玉仁】0.概述 【大模型基础_毛玉仁】1.1 基于统计方法的语言模型 更新中。。。。。。 参考 书籍&#xff1a;大模型基础_完整版.pdf Github&#xff1a;https://github.co…