详细总结前中后序、层次遍历二叉树(非递归方法)

2024-04-03 09:12

本文主要是介绍详细总结前中后序、层次遍历二叉树(非递归方法),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

二叉树

结构

//二叉树节点结构
class Node<V>{V value;Node left;Node right;}

之前一直学的是用递归方法进行前中后序三种遍历方法,没想到用非递归方法也还是挺舒服的,对了解树结构的应用也很有帮助 (主要用到的思路就是借助栈或者队列讲树的结点进栈或者队列后,弹出打印后,再将此节点的左右孩子进栈或者队列,这个思路上的基础上不断变化找到契合你想要的结果的答案)

1)前序遍历

借用一个栈,先将树的头结点入栈,然后通过一个while循环,**头结点出栈,并将其打印,**然后将此结点的右孩子和左孩子依次入栈(注意是先放入右孩子再放入左孩子)因为要想是先序遍历的话,应该是头->左->右的顺序,所以偷出来以后应该出来左孩子,根据栈后进先出的原理,所以先放右孩子进栈,然后左孩子进栈

这里注意一下,是每次出一个结点,就要将其右孩子和左孩子进栈,最后才满足先序遍历的结果,如果以后看的懵逼的话最好拿纸画一画,然后上代码:

public static void preOrderUnRecur(Node head) {if (head != null) {Stack<Node> stack = new Stack<Node>();stack.add(head);while (!stack.isEmpty()) {head = stack.pop();      //如果是C++的话,这里应该分两步 head=stack.top(); stack.pop();System.out.print(head.value + " ");if (head.right != null) {stack.push(head.right);}if (head.left != null) {stack.push(head.left); }}}
}

2)后序遍历

后序遍历有点像是先序遍历的升级版,这里需要借助两个栈,第一个栈和上面功能一样,头结点进去之后然后出来的同时只不过不是先将右孩子放进去了,而是将左孩子先放进去再将右孩子放进去

第二个栈是用来寄存第一个栈中取出的结点,从第一个栈中弹出的结点就保存在第二个栈中,最后依次弹出第二个栈中的结点就是后序遍历的结果

这个方法经典就在两个栈的结合应用,注意这种方法,代码如下:

public static void posOrderUnRecur1(Node head) {if (head != null) {Stack<Node> s1 = new Stack<Node>();Stack<Node> s2 = new Stack<Node>();s1.add(head);while (!s1.isEmpty()) {head = s1.pop();    //这里如果用C++的话同上面讲的需要拆解成两步s2.add(head);	    //从第一个栈弹出的结点放入第二个栈if (head.left != null) s1.add(head.left);  if (head.right != null) s1.add(head.right); }while (!s2.isEmpty()) {System.out.print(s2.pop().value + " ");}}
}

3)中序遍历

中序和之前都不太一样了,还是借助一个栈,从头结点开始每棵子树整树的左孩子全部进栈,直到没有左孩子位置的时候停止;

依次弹出的过程中打印

并且对弹出的结点的右树进行如上同样的操作,也就是说对右树及其所有子树中的左孩子依次进栈,周而复始。

至于为什么这么想就可以实现,可以想一下,每次都是将左侧的所有结点入栈之后,结点弹出的时候肯定是先弹出左节点然后是父节点,然后打印了父节点之后又将右节点入栈之后重复上面步骤,所以最后顺序不就是左上右嘛:

左头{左头【左头(左头右)】},代码如下:

public static void inOrderUnRecur(Node head) {if (head != null) {Stack<Node> stack = new Stack<Node>();while (!stack.isEmpty() || head != null) {if (head != null) {   //从头结点开始将其左子树以及他们的左孩子都进栈stack.add(head);head = head.left;} else {head = stack.pop();  //直到最后一个左孩子是叶节点没有左孩子后,开始出栈System.out.print(head.value + " ");head = head.right;   //继续走先前的逻辑}}}
}

4)二叉树的层次遍历

(主要用到的思路就是借助栈或者队列讲树的结点进栈或者队列后,弹出打印后,再将此节点的左右孩子进栈或者队列,这个个思路上的基础上不断变化找到契合你想要的结果的答案)

借助一个队列轻松解决,和上面先序遍历的思路相似,但是这里用的变成了队列

并且是弹出一个结点就是先将其左孩子放进去再将其右孩子放进去

根据队列先进先出的性质可以明显想出就是层次遍历

public static void leveltree(Node head){if(head == null)return;Queue<Node> queue = new LinkedList<>();queue.add(head);while(!queue.isEmpty()){Node cur = queue.poll();System.out.println(cur);if(cur.left != null)queue.add(cur.left);if(cur.right != null)queue.add(cur.right);}
}

这篇关于详细总结前中后序、层次遍历二叉树(非递归方法)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/872498

相关文章

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

Python列表去重的4种核心方法与实战指南详解

《Python列表去重的4种核心方法与实战指南详解》在Python开发中,处理列表数据时经常需要去除重复元素,本文将详细介绍4种最实用的列表去重方法,有需要的小伙伴可以根据自己的需要进行选择... 目录方法1:集合(set)去重法(最快速)方法2:顺序遍历法(保持顺序)方法3:副本删除法(原地修改)方法4:

Python中判断对象是否为空的方法

《Python中判断对象是否为空的方法》在Python开发中,判断对象是否为“空”是高频操作,但看似简单的需求却暗藏玄机,从None到空容器,从零值到自定义对象的“假值”状态,不同场景下的“空”需要精... 目录一、python中的“空”值体系二、精准判定方法对比三、常见误区解析四、进阶处理技巧五、性能优化

如何在Mac上安装并配置JDK环境变量详细步骤

《如何在Mac上安装并配置JDK环境变量详细步骤》:本文主要介绍如何在Mac上安装并配置JDK环境变量详细步骤,包括下载JDK、安装JDK、配置环境变量、验证JDK配置以及可选地设置PowerSh... 目录步骤 1:下载JDK步骤 2:安装JDK步骤 3:配置环境变量1. 编辑~/.zshrc(对于zsh

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

如何将Python彻底卸载的三种方法

《如何将Python彻底卸载的三种方法》通常我们在一些软件的使用上有碰壁,第一反应就是卸载重装,所以有小伙伴就问我Python怎么卸载才能彻底卸载干净,今天这篇文章,小编就来教大家如何彻底卸载Pyth... 目录软件卸载①方法:②方法:③方法:清理相关文件夹软件卸载①方法:首先,在安装python时,下

电脑死机无反应怎么强制重启? 一文读懂方法及注意事项

《电脑死机无反应怎么强制重启?一文读懂方法及注意事项》在日常使用电脑的过程中,我们难免会遇到电脑无法正常启动的情况,本文将详细介绍几种常见的电脑强制开机方法,并探讨在强制开机后应注意的事项,以及如何... 在日常生活和工作中,我们经常会遇到电脑突然无反应的情况,这时候强制重启就成了解决问题的“救命稻草”。那

kali linux 无法登录root的问题及解决方法

《kalilinux无法登录root的问题及解决方法》:本文主要介绍kalilinux无法登录root的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录kali linux 无法登录root1、问题描述1.1、本地登录root1.2、ssh远程登录root2、

SpringMVC获取请求参数的方法

《SpringMVC获取请求参数的方法》:本文主要介绍SpringMVC获取请求参数的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下... 目录1、通过ServletAPI获取2、通过控制器方法的形参获取请求参数3、@RequestParam4、@

Python中的魔术方法__new__详解

《Python中的魔术方法__new__详解》:本文主要介绍Python中的魔术方法__new__的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、核心意义与机制1.1 构造过程原理1.2 与 __init__ 对比二、核心功能解析2.1 核心能力2.2