二叉树的非递归遍历|前中后序遍历

二叉树的非递归遍历

文章目录

    • 二叉树的非递归遍历
      • 前序遍历-栈
      • 层序遍历-队列
      • 中序遍历-栈
      • 后序遍历-栈

前序遍历-栈

首先我们应该创建一个Stack 用来存放节点,首先我们想要打印根节点的数据,此时Stack里面的内容为空,所以我们优先将头结点加入Stack。之后我们应该先打印左子树,然后右子树,所以先加入Stack的就是右子树,然后左子树。

public List<Integer> preorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();if (root == null) {return res;}Stack<TreeNode> stack = new Stack<>();//1.根节点入栈stack.push(root);//2.栈不为空while (!stack.isEmpty()) {//2.1出栈,需暂时保存出栈元素TreeNode tmp = stack.pop();res.add(tmp.val);//2.2左右子树不为空的情况下,出栈元素的右子树入栈,左子树入栈if (tmp.right != null) {stack.push(tmp.right);}if (tmp.left != null) {stack.push(tmp.left);}}return res;
}

层序遍历-队列

首先我们应该创建一个Queue用来存放节点,首先我们想要打印根节点的数据,此时Queue里面的内容为空,所以我们优先将头结点加入Queue。之后我们应该先打印左子树,然后右子树,所以先加入Queue的就是左子树,然后右子树。

public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> res = new ArrayList<>();if (root == null) {return res;}Queue<TreeNode> queue = new LinkedList<>();//1.根节点入队列queue.offer(root);//2.队列不为空while (!queue.isEmpty()) {//2.1获取当前队列的元素List<Integer> level = new ArrayList<>();int size = queue.size();for (int i = 0; i < size; i++) {//2.1.1出队列,需暂时保存出队元素TreeNode tmp = queue.poll();level.add(tmp.val);//2.1.2左右子树不为空的情况下,出队元素的左子树入队,右子树入队if (tmp.left != null) {queue.offer(tmp.left);}if (tmp.right != null) {queue.offer(tmp.right);}}//2.2当前队列元素加入到res中res.add(level);}return res;
}

中序遍历-栈

同理创建一个 Stack。

尽可能的将这个节点的左子树压入 Stack,此时栈顶的元素是最左侧的元素,其目的是找到一个最小单位的子树(也就是最左侧的一个节点),并且在寻找的过程中记录了来源,才能返回上层,同时在返回上层的时候已经处理完毕左子树了。

当处理完最小单位的子树时,返回到上层处理了中间节点。(如果把整个左中右的遍历都理解成子树的话,就是处理完 左子树->中间(就是一个节点)->右子树)

如果有右节点,其也要进行中序遍历。

public List<Integer> inorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();if (root == null) {return res;}Stack<TreeNode> stack = new Stack<>();TreeNode cur = root;while (true) {//1.cur从根节点出发,一直向左保存左子树,直到cur=nullwhile (cur != null) {stack.push(cur);cur = cur.left;}//2.若栈为空,退出循环if (stack.isEmpty()) {break;}//3.出栈TreeNode tmp = stack.pop();res.add(tmp.val);//4.cur指向出栈元素的右子树,//若为空则继续出栈,若不为空再继续向左保存子树cur = tmp.right;}return res;
}

后序遍历-栈

同理创建一个 Stack。

尽可能的将这个节点的左子树压入 Stack,此时栈顶的元素是最左侧的元素

该元素无右子树,或者右子树已经访问过,则可以处理该元素,并用prev记录当前已处理的元素

否则访问右子树,进行后序遍历

    public List<Integer> postorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();if (root == null) {return res;}Stack<TreeNode> stack = new Stack<>();TreeNode cur = root;TreeNode prev = null;while (true) {//1.cur从根节点出发一直向左保存左子树,直到cur=nullwhile (cur != null) {stack.push(cur);cur = cur.left;}//2.若栈为空,退出循环if (stack.isEmpty()) {break;}//3.得到栈顶元素,先不访问(满足条件才可以访问)TreeNode tmp = stack.peek();//4.若栈顶元素无右子树或者右子树已被访问,则可以访问//若prev==tmp.right,则tmp一定是其右子树的根节点。因为此时右子树已访问完毕if (tmp.right == null || tmp.right == prev) {stack.pop();res.add(tmp.val);prev = tmp;} else { //5.cur指向栈顶元素的右子树cur = tmp.right;}}return res;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499546.shtml

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

相关文章

C#灰度图转伪彩色图

/// <summary>/// 伪彩色图像构造器/// </summary>public class PseudoColorImageBuilder{/// <summary>/// 铁红色带映射表/// 每一行代表一个彩色分类&#xff0c;存放顺序是RGB/// </summary>public static byte[,] ironTable new byte[128, 3] {{…

砥志研思SVM(二) 拉格朗日乘子法与KKT条件

[1]最优化问题中的对偶性理论 [2]拉格朗日乘子法(上) [3]拉格朗日乘子法(下)

VS2015上配置opencv2.4.11

VS2015上配置opencv2.4.11版方法总结 最近给电脑重装了系统&#xff0c;需要的软件各种装。今天阅读了很多网上的博客&#xff0c;几经波折完成了opencv的配置。配置opencv与其他函数包或者软件相比算是麻烦的了&#xff0c;可能出现的问题也是五花八门&#xff0c;所以针对我的…

热传导方程的差分格式原理与matlab实现

function [ ] ParabolicEquation( h,k ) %求解抛物型方程中的一种&#xff1a;热传导方程 %h:x轴步长 %k:t轴步长rk/(h*h);%网格比 Mxfloor(1.0/h)1;%网格在x轴上的节点个数&#xff08;算上0&#xff09; Ntfloor(1.0/k)1;%网格在t轴上的节点个数&#xff08;算上0&#xff…

如何开发一个扫雷小游戏?

如何用C#开发一个扫雷小游戏&#xff1f; 十分自豪的说&#xff0c;计算机编程就是变魔术&#xff0c;每一个coder都是一个魔术师。 初学C#的时候&#xff0c;我相信很多人都和我一样&#xff0c;学会了基本语法&#xff0c;掌握了基本的数据结构&#xff0c;也见过了不少微软…

在emIDE中创建STM32项目

&#xfeff;emIDE是一个开源的嵌入式集成开发环境&#xff0c;基于Code::Blocks开发&#xff0c;能够支持多个平台和多个厂家的嵌入式硬件&#xff0c;继承了Code::Blocks的优点。 下载emIDE并安装&#xff0c;也可选择绿色版。若需要调试则需安装J-Link GDB Server。 1、打…

“Hello,Github!——如何配置并上传一个已有项目到Git上

“Hello&#xff0c;Github!"——如何配置并上传一个已有项目到Git上注意&#xff01;前言十分简短&#xff01;如今&#xff0c;Github已经成为了管理软件开发以及发现别人优秀代码的首选方法。所以还在等什么&#xff01;快点跟上脚步&#xff01;今天初次注册了Github账…

使用EmBitz开发STM32项目开发环境配置

&#xfeff;&#xfeff; 一、EmBitz软件获取与安装 1、EmBitz软件的获取 EmBitz原名Em::Blocks&#xff0c;是基于Code::Blocks开发的&#xff0c;面向嵌入式的C/C集成开发环境。支持J-Link和ST-Link调试器。使用J-Link仿真器时需安装J-Link GDB Server。 EmBitz下载地址&…

Python格式化输出方法

Python格式化输出 本文转自&#xff1a;Python格式化输出 今天写程序又记不清格式化输出细节了…… 索性整理一下。 python print格式化输出。 1. 打印字符串 print ("His name is %s"%("Aviad")) 效果&#xff1a; 2.打印整数 print ("He is %d yea…

基于STM32和W5500的Modbus TCP通讯

&#xfeff;&#xfeff; 在最近的一个项目中需要实现Modbus TCP通讯&#xff0c;而选用的硬件平台则是STM32F103和W5500&#xff0c;软件平台则选用IAR EWAR6.4来实现。 1、移植前的准备工作 为了实现Modbus TCP通讯首先需要下载W5500的驱动源码&#xff0c;可以到WIZnet的…

Python小练习1:.txt文件常用读写操作

.txt文件常用读写操作 本文通过一个实例来介绍读写txt文件的各种常用操作&#xff0c;问题修改自coursera上南京大学的课程&#xff1a;用Python玩转数据。 直接进入正题&#xff0c;考虑下面为练习读写txt文件的各种操作而设计的一个具体问题 问题如下&#xff1a; (1) 在任意…

STM32F103使用内部Flash保存参数

&#xfeff;&#xfeff; 在我们应用开发时&#xff0c;经常会有一些程序运行参数需要保存&#xff0c;如一些修正系数。这些数据的特点是&#xff1a;数量少而且不需要经常修改&#xff0c;但又不能定义为常量&#xff0c;因为每台设备可能不一样而且在以后还有修改的可能。…

Python序列类型常用函数练习:enumerate() reversed() sorted() zip()

Python序列类型常用函数练习 这里使用代码示例&#xff0c;练习使用序列类型的常用函数&#xff0c;包括&#xff1a; enumerate() reversed() sorted() zip() 直接看python代码 #enumerate--------------------------------------------------------------------- #enume…

FreeRTOS学习及移植笔记之一:开始FreeRTOS之旅

&#xfeff;&#xfeff; 1、必要的准备工作 工欲善其事&#xff0c;必先利其器&#xff0c;在开始学习和移植之前&#xff0c;相应的准备工作必不可少。所以在开始我们写要准备如下: 测试环境&#xff1a;我准备在STM32F103平台上移植和测试FreeRTOS系统 准备FreeRTOS系统…

Python小练习2:pandas.Dataframe使用方法示例demo

pandas.Dataframe使用方法示例demo 本文通过一个实例来介绍pandas.Dataframe的各种常用操作&#xff0c;问题总结并修改自coursera上南京大学的课程&#xff1a;用Python玩转数据。 直接进入正题&#xff0c;我们的示例首先调用matplotlib.finance包中提供的函数quotes_histor…