三种非递归遍历二叉树的方法

article/2025/9/22 17:09:08

在这里插入图片描述
   就以这个树为例,来讲讲二叉树的非递归遍历。

先序遍历: 先序遍历结果为3 4 6 5 8 9,就拿树的左枝为例,3是根,打印,4是3的左孩子,打印,6是4的左孩子,打印,6的左孩子为空,所以返回到4,然后去找4的右孩子,4的右孩子也为空,返回到3,这就是左子树遍历的过程。然后非递归主要用到栈来存储结点,栈先进后出,所以应该是右孩子先入栈,左孩子后入栈,这样pop就能先得到左孩子。先将根结点3入栈,接下来就是开始循环,循环结束的条件就是栈为空,先弹出栈顶,再打印栈顶,如果栈顶的右孩子不为null,就把右孩子放进栈中,如果栈顶的左孩子不为null,就把左孩子放入栈中。
用下面一幅图来说明整个过程
在这里插入图片描述

void pretravel2(TreeNode root) {if (root == null) return;Stack<TreeNode> s = new Stack<TreeNode>();s.push(root);while (!s.isEmpty()) {TreeNode node = s.pop();System.out.print(node.val+" ");if (node.right != null) {s.push(node.right);}if (node.left != null) {s.push(node.left);}}}

中序遍历:中序遍历的结果为6 4 3 8 5 9,其实就是左遍历完了,弹出根,找根的右结点,整个过程是先一路找左结点,找到左结点为null的6,然后找6的根4,接着找4的右,为null,接着找4的根3,接着一路找3的左,直到结点的左孩子为null,这就找到了8,然后找8的根5,再找5的右9,这样就找完了。他们的入栈出栈顺序:根结点入栈,左孩子直接入栈,并且标记这个结点已经走过,以防后面再走,当发现哪个结点的左孩子为null的时候,就打印这个结点,并且将这个结点出栈,让他的右孩子入栈
在这里插入图片描述

 void intravel2(TreeNode root) {if(root==null)return ;Stack<TreeNode> stack=new Stack<>();stack.push(root);//使用list来标记结点是否走过List<TreeNode> list=new ArrayList<>();while(!stack.isEmpty()) {//只需要拿到根结点,不需要pop出来TreeNode peek = stack.peek();//如果左孩子不为null并且左孩子没有被走过,就把他放到栈里,并且标记为走过if(peek.left!=null&& !list.contains(peek.left)) {stack.push(peek.left);list.add(peek.left);}else {//左孩子为空,打印根结点,根结点出栈,右孩子进栈TreeNode pop = stack.pop();System.out.print(pop.val+" ");if(pop.right!=null)stack.push(pop.right);}}}

中序遍历还有另外一种写法:

 void intravel3(TreeNode root) {Stack<TreeNode> stack=new Stack<>();TreeNode p=root;while(p!=null||!stack.isEmpty()) {while(p!=null) {stack.push(p);p=p.left;}//左孩子遍历完了,根结点弹出,打印根结点,遍历右孩子if(!stack.isEmpty()) {TreeNode temp=stack.pop();System.out.print(temp.val+" ");p=temp.right;}}}

后序遍历: 后序遍历的结果为6 4 8 9 5 3,一路找左结点到6,然后找到右孩子为null,退到根4,4的右为null,然后3的左孩子遍历完了,到右孩子,一路找左孩子到8,右孩子9,根5,右孩子遍历完,最后到4。他们的进栈出栈顺序为:根结点入栈,左孩子一路入栈,当有个结点的左孩子为null的时候,就将它的右孩子入栈,如果右孩子也为null,才打印根结点。
在这里插入图片描述

void postrval2(TreeNode root) {if(root==null)return ;Stack<TreeNode> stack=new Stack<>();stack.push(root);List<TreeNode> list=new ArrayList<>();while(!stack.isEmpty()) {TreeNode peek=stack.peek();//先一路走左,左走完了才到右if(peek.left!=null&&!list.contains(peek.left)) {//如果左结点不为null并且左结点没有走过//就将其压入栈中,并且标记已经走过stack.push(peek.left);list.add(peek.left);}else {if(peek.right!=null&&!list.contains(peek.right)) {//如果右结点为不为null并且右结点没有走过//就将右结点压入栈中,标记已经走过stack.push(peek.right);list.add(peek.right);}else {//如果右孩子为null,就打印根结点TreeNode pop = stack.pop();System.out.print(pop.val+" ");}}}}

递归遍历,非递归遍历的代码

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;import java.util.*;class TreeNode {int val;TreeNode left=null;TreeNode right=null;TreeNode(){}TreeNode(int val) {this.val=val;}
}public class Main {public static void main(String[] args) {Main main = new Main();TreeNode root=null;root=main.createTree();System.out.println("先序遍历:");main.pretravel(root);System.out.println("");System.out.println("中序遍历:");main.intravel(root);System.out.println("");System.out.println("后序遍历:");main.postravel(root);System.out.println("");System.out.println("迭代先序遍历:");main.pretravel2(root);System.out.println("");System.out.println("迭代中序遍历1(类似于回溯算法):");main.intravel2(root);System.out.println("");System.out.println("迭代中序遍历2:");main.intravel3(root);System.out.println("");System.out.println("迭代后序遍历:");main.postrval2(root);System.out.println("");System.out.println("层序遍历:");main.levelOrder(root);}//建树TreeNode createTree(){Scanner sc=new Scanner(System.in);int temp=sc.nextInt();if(temp<=0)return null;TreeNode root=new TreeNode();root.val=temp;root.left=createTree();root.right=createTree();return root;}//先序void pretravel(TreeNode root){if(root==null)return;System.out.print(root.val+" ");pretravel(root.left);pretravel(root.right);}//中序void intravel(TreeNode root){if(root==null)return;intravel(root.left);System.out.print(root.val+" ");intravel(root.right);}//后序void postravel(TreeNode root){if(root==null)return;postravel(root.left);postravel(root.right);System.out.print(root.val+" ");}//迭代先序void pretravel2(TreeNode root) {if (root == null) return;Stack<TreeNode> s = new Stack<TreeNode>();s.push(root);while (!s.isEmpty()) {TreeNode node = s.pop();System.out.print(node.val+" ");if (node.right != null) {s.push(node.right);}if (node.left != null) {s.push(node.left);}}}void intravel2(TreeNode root) {if(root==null)return ;Stack<TreeNode> stack=new Stack<>();stack.push(root);List<TreeNode> list=new ArrayList<>();while(!stack.isEmpty()) {TreeNode peek = stack.peek();if(peek.left!=null&& !list.contains(peek.left)) {stack.push(peek.left);list.add(peek.left);}else {//左孩子为空,打印根结点,根结点出栈,右孩子进栈TreeNode pop = stack.pop();System.out.print(pop.val+" ");if(pop.right!=null)stack.push(pop.right);}}}void intravel3(TreeNode root) {Stack<TreeNode> stack=new Stack<>();TreeNode p=root;while(p!=null||!stack.isEmpty()) {while(p!=null) {stack.push(p);p=p.left;}if(!stack.isEmpty()) {TreeNode temp=stack.pop();System.out.print(temp.val+" ");p=temp.right;}}}void postrval2(TreeNode root) {if(root==null)return ;Stack<TreeNode> stack=new Stack<>();stack.push(root);List<TreeNode> list=new ArrayList<>();while(!stack.isEmpty()) {TreeNode peek=stack.peek();if(peek.left!=null&&!list.contains(peek.left)) {stack.push(peek.left);list.add(peek.left);}else {if(peek.right!=null&&!list.contains(peek.right)) {stack.push(peek.right);list.add(peek.right);}else {TreeNode pop = stack.pop();System.out.print(pop.val+" ");}}}}//层序void levelOrder(TreeNode root) {List<TreeNode> list=new ArrayList<>();list.add(root);while(list.size()!=0) {TreeNode temp=list.get(0);if(temp.left!=null) list.add(temp.left);if(temp.right!=null) list.add(temp.right);list.remove(0);System.out.print(temp.val+" ");}}
}

输入是按照先序序列输,输一个打一个回车,结点为null的时候输入-1,表示为空,叶子节点要输两个-1,表示左右孩子均为空。
在这里插入图片描述
在这里插入图片描述


http://chatgpt.dhexx.cn/article/Hr2233Bd.shtml

相关文章

二叉树的非递归遍历

目录 一.前序遍历&#xff08;根左右&#xff09; 1.思路图解 2.代码 二.中序遍历&#xff08;左根右&#xff09; 1.思路图解 2.代码 三.后序遍历&#xff08;左右根&#xff09; 1.思路图解 2.代码 四.层序遍历 1.思路图解 2.代码 一.前序遍历&#xff08;根左右…

smile——Java机器学习引擎

介绍 Smile&#xff08;统计机器智能和学习引擎&#xff09;是一个基于Java和Scala的快速、全面的机器学习、NLP、线性代数、图形、插值和可视化系统。 凭借先进的数据结构和算法&#xff0c;Smile提供了最先进的性能。Smile有很好的文档记录&#xff0c;请查看项目网站以获取…

Java机器学习库(Java ML)(一、分类)

本文章翻译至Java ML技术文档classification.pdf&#xff0c;代码部分是参考该文档使用IDEA编写&#xff0c;同时加入了运行结果。 分类 本文介绍与分类相关的功能。 该文章假设您已熟悉Java ML的基础知识&#xff0c;如入门教程中所述&#xff08;http://java-ml.sourcefor…

目前流行的、强大的基于Java的机器学习开发库精选

图片来源: Mindfire Solutions 现如今&#xff0c;拥有深度学习和机器学习领域的技术是科技界的趋势之一&#xff0c;并且企业则希望雇佣一些拥有良好的机器学习知识背景的程序开发工程师。本文将介绍一些目前流行的、强大的基于Java的机器学习库&#xff0c;希望给大家带来帮助…

JAVA 人工神经网络实现,机器学习,人工智能

人工智能&#xff08;AI&#xff09; 、机器学习&#xff08;ML&#xff09;、深度学习&#xff08;DL&#xff09;、神经网络&#xff08;CNN&#xff09; IT技术圈的人怼这些词汇大家都一定耳熟能详了&#xff0c;可能圈外的也不陌生&#xff0c;但是作为一个作为一个“攻城…

机器学习java_如何开始使用Java机器学习

机器学习java 什么是开始使用Java机器学习的最佳工具&#xff1f; 他们已经存在了一段时间&#xff0c;但如今看来&#xff0c;每个人都在谈论人工智能和机器学习。 对于科学家和研究人员而言&#xff0c;它已经不再是秘密&#xff0c;几乎可以在任何新兴技术中实现。 在下面…

谁说搞Java的不能玩机器学习?

简介 机器学习在全球范围内越来越受欢迎和使用。 它已经彻底改变了某些应用程序的构建方式&#xff0c;并且可能会继续成为我们日常生活中一个巨大的&#xff08;并且正在增加的&#xff09;部分。没有什么包装且机器学习并不简单。 它对许多人来说似乎非常复杂并常常令人生畏…

基于 Java 机器学习自学笔记 (第51-53天:kNN)

注意&#xff1a;本篇为50天后的Java自学笔记扩充&#xff0c;内容不再是基础数据结构内容而是机器学习中的各种经典算法。这部分博客更侧重与笔记以方便自己的理解&#xff0c;自我知识的输出明显减少&#xff0c;若有错误欢迎指正&#xff01; 目录 一、关于数据集及其导入…

基于 Java 机器学习自学笔记 (第66至68天:主动学习之ALEC)

注意&#xff1a;本篇为50天后的Java自学笔记扩充&#xff0c;内容不再是基础数据结构内容而是机器学习中的各种经典算法。这部分博客更侧重于笔记以方便自己的理解&#xff0c;自我知识的输出明显减少&#xff0c;若有错误欢迎指正&#xff01; 目录 前言 一、关于学习的分类…

超全!基于Java的机器学习项目、环境、库...

https://yq.aliyun.com/articles/278837?utm_sourcetuicool&utm_mediumreferral 摘要&#xff1a; 你是一名希望开始或者正在学习机器学习的Java程序员吗&#xff1f; 利用机器学习编写程序是最佳的学习方式。你可以从头开始编写算法&#xff0c;但是利用现有的开源库&am…

结合Java和机器学习技术,如何驾驭大数据提升业务效率和竞争力?

随着大数据的不断增长和发展&#xff0c;越来越多的企业和组织开始关注如何利用大数据来提高业务效率和竞争力。在大数据分析领域&#xff0c;Java和机器学习技术是两个非常重要的方向。本文将介绍这两个技术的基本概念、应用场景和发展趋势&#xff0c;并重点探讨如何结合Java…

25个JAVA 机器学习工具包

本列表总结了25个Java机器学习工具&库&#xff1a; 1. Weka集成了数据挖掘工作的机器学习算法。这些算法可以直接应用于一个数据集上或者你可以自己编写代码来调用。Weka包括一系列的工具&#xff0c;如数据预处理、分类、回归、聚类、关联规则以及可视化。 2.Massive Onli…

7个最好的Java机器学习开发库

IT派 - {技术青年圈} 持续关注互联网、区块链、人工智能领域 摘要&#xff1a; 本文将介绍一些目前流行的、强大的基于Java的机器学习库。 图片来源: Mindfire Solutions 摘要&#xff1a;现如今&#xff0c;拥有深度学习和机器学习领域的技术是科技界的趋势之一&#xff0c;并…

基于 Java 机器学习自学笔记 (第71-73天:BP神经网络)

注意&#xff1a;本篇为50天后的Java自学笔记扩充&#xff0c;内容不再是基础数据结构内容而是机器学习中的各种经典算法。这部分博客更侧重于笔记以方便自己的理解&#xff0c;自我知识的输出明显减少&#xff0c;若有错误欢迎指正&#xff01; 前言 本文是我计划描述BP神经网…

如何开始Java机器学习

什么是开始使用Java机器学习的最佳工具&#xff1f; 他们已经存在了一段时间&#xff0c;但如今看来&#xff0c;每个人都在谈论人工智能和机器学习。 对于科学家和研究人员而言&#xff0c;它已不再是秘密&#xff0c;几乎可以在任何新兴技术中实现。 在下面的文章中&#x…

如何开始使用 Java 机器学习

开始Java机器学习的最好工具是什么&#xff1f; 这个问题已经有一段时间了&#xff0c;但最近这些日子几乎每个人都在谈论人工智能和机器学习。这已经不再是一个保留给科学家和研究者的秘密&#xff0c;而是几乎实现于每一项新兴技术中。 在下面的章节中&#xff0c;我们会做一…

6大最常用的Java机器学习库一览

导读&#xff1a;机器学习是目前盛行于世的技术之一&#xff0c;这几年一时风头无两。虽然在机器学习中&#xff0c;Python是人工智能从业者使用最多的编程语言&#xff0c;但是&#xff0c;Java 在项目开发中仍然发挥着不可替代的作用&#xff0c;而且许多流行的机器学习框架本…

基于 Java 机器学习自学笔记 (第60天:过去十日的总结)

注意&#xff1a;本篇为50天后的Java自学笔记扩充&#xff0c;内容不再是基础数据结构内容而是机器学习中的各种经典算法。这部分博客更侧重于笔记以方便自己的理解&#xff0c;自我知识的输出明显减少&#xff0c;若有错误欢迎指正&#xff01; 目录 1.尝试作为知识的输出者 …

机器学习入门-用Java实现简单感知机

一、通俗理解机器学习 1、机器学习是人工智能的一种&#xff0c;如图所示&#xff0c;它是人工智能的一个子方向。 2、机器学习有点像人类的学习过程。 1. 人类学习通过经验(事件)&#xff0c;归纳出规律。 2. 机器学习通过数据&#xff0c;训练出模型。 3、机器学习不是基于编…

机器学习算法 java_Java开发人员的机器学习,第1部分:机器学习算法

机器学习算法 java 无人驾驶汽车&#xff0c;面部检测软件和语音控制扬声器均基于机器学习技术和框架构建&#xff0c;而这些仅仅是第一波。 在接下来的十年中&#xff0c;新一代产品将改变我们的世界&#xff0c;为软件开发以及我们创建和使用的应用程序和产品启动新的方法。 …