二叉树的先序遍历

数据访问顺序:根结点------->左孩子------->又孩子

使用递归

使用了分治法:将一个大树向下一层层的分为多个小子树

/*** 先序遍历,使用递归,输出树中所有结点* @param rootNode 根结点*/public static void preOrder(TreeNode rootNode) {TreeNode moveNode = rootNode;if(moveNode != null) {System.out.print(moveNode.getData()+" ");preOrder(moveNode.getLeChild());preOrder(moveNode.getRiChild());}}

使用栈

利用栈的特性:对每个小子树的根结点进行存储,使得访问左子树后,右子树的追踪不会丢失
数据在入栈时进行访问

/*** 使用栈来进行先序遍历* @param rootNode  根结点*/public static void stackPreOrder(TreeNode rootNode) {TreeNode moveNode = rootNode;//构造长度为10的栈TreeNode[] stack = new TreeNode[10];int i = 0;//栈不为空且还有数据while(moveNode != null || i != 0) {while(moveNode != null) {//遍历左子树入栈stack[i++] = moveNode;System.out.print(moveNode.getData()+" ");moveNode = moveNode.getLeChild();}while((moveNode = stack[--i].getRiChild()) == null) {if(i == 0) {//当栈空,还没有右子树,遍历结束return;}}}  }

PS:在这里我使用循环嵌套,可能美观性有点不太好,但易于理解

二叉树的中序遍历

数据访问顺序:左孩子------->根结点------->右孩子

使用递归

大致和先序遍历相同

/*** 中序遍历,使用递归* @param rootNode 根结点*/public static void inOrder(TreeNode rootNode) {TreeNode moveNode = rootNode;if(moveNode != null) {inOrder(moveNode.getLeChild());System.out.print(moveNode.getData()+" ");inOrder(moveNode.getRiChild());}}

使用栈

数据的输出位置发生变化,即在出栈位置进行访问

/*** 使用栈完成中序遍历* @param rootNode   根结点*/public static void stackInOrder(TreeNode rootNode) {TreeNode moveNode = rootNode;TreeNode[] stack = new TreeNode[10];int i = 0;//栈不为空,且还有数据while(moveNode != null || i != 0) {while(moveNode != null) {//遍历左子树入栈stack[i++] = moveNode;moveNode = moveNode.getLeChild();}//循环出栈,找出右子树未空的结点while((moveNode = stack[--i].getRiChild()) == null) {//若无右子树,直接输出当前结点值System.out.print(stack[i].getData()+" ");if(i == 0) {//当栈空,还没有右子树,遍历结束return;}}//输出有右子树的结点值System.out.print(stack[i].getData()+" ");}}

二叉树的后序遍历

数据访问顺序:左孩子------->右孩子------->根结点

使用递归

大致和先序遍历相同

/*** 后序遍历,使用递归* @param rootNode 根结点*/public static void postOrder(TreeNode rootNode) {TreeNode moveNode = rootNode;if(moveNode != null) {postOrder(moveNode.getLeChild());postOrder(moveNode.getRiChild());System.out.print(moveNode.getData()+" ");}}

使用栈

由于后续遍历的特殊性,若子树根结点有右子树,则需先遍历子树的右子树,再输出子树根结点,此处需要对根结点进行二次访问(第一次得到右子树的入口,第二次访问数据)。若根结点直接出栈,会导致追踪丢失,因此设一个标记对子树根结点进行判断。
判断内容:是否为第一次访问

/*** 借用栈完成后序遍历* @param rootNode  根结点*/public static void stackPostOrder(TreeNode rootNode) {TreeNode moveNode = rootNode;//构造长度为10的栈TreeNode[] stack = new TreeNode[20];//设置标记数组,和栈同步操作,0为入栈,1为遇到一次int[] mark = new int[20];int i = 0;int j = 0;//将根归栈 //栈不为空时while(moveNode != null || i != 0) {if(moveNode != null) {stack[i++] = moveNode;mark[j++] = 0;moveNode = moveNode.getLeChild();}else {//无右子树,直接输出if(stack[i-1].getRiChild() == null) { System.out.print(stack[--i].getData()+" ");j--;moveNode = null;}else if(stack[i-1].getRiChild() != null && mark[j-1] != 1) {//若即将出栈结点有右子树且标记为0时,则不出栈只取值moveNode = stack[i-1].getRiChild();mark[i-1] = 1; //修改标记}else if(stack[i-1].getRiChild() != null && mark[j-1] == 1) {//在遍历完右子树之后,出栈,直接输出System.out.println(stack[--i]+" ");j--;moveNode = null;}}}}

PS:此处只使用了一个主循环,之前的遍历也可统一为一个主循环

测试

测试树:

测试调用:

System.out.print("使用递归的先序遍历:");preOrder(rootNode);System.out.print("\r\n"+"使用递归的中序遍历:");inOrder(rootNode);System.out.print("\r\n"+"使用递归的后序遍历:");postOrder(rootNode);System.out.print("\r\n"+"使用栈的先序遍历:");stackPreOrder(rootNode);System.out.print("\r\n"+"使用栈的中序遍历:");stackInOrder(rootNode); System.out.print("\r\n"+"使用栈的后序遍历:");postOrder(rootNode);

测试结果:

二叉树的三种遍历(递归,栈)相关推荐

  1. 二叉树的三种遍历(递归与非递归) + 层次遍历

    <转载于  >>> > 二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的.二叉树有前.中.后三种遍历方式,因为树的本身就是用递归定义的,因此 ...

  2. 实现二叉树的三种非递归遍历算法

    [问题描述] 编写程序,实现二叉树的三种非递归遍历算法:先序非递归,中序非递归,后序非递归. [输入形式] 输入建树序列. [输出形式] 输出三种遍历序列. [样例输入] A B C # # # # ...

  3. 二叉树的三种遍历方式(递归、非递归和Morris遍历)

    二叉树的三种遍历方式(递归.非递归和Morris遍历) 原文:http://www.linuxidc.com/Linux/2015-08/122480.htm 二叉树遍历是二叉树的最基本的操作,其实现 ...

  4. 详解二叉树的三种遍历方式(递归、迭代、Morris算法)

    详解二叉树的三种遍历方式(递归.迭代.Morris算法) 最重要的事情写在前面:遍历顺序不一定就是操作顺序!!! 递归解法 首先,一颗二叉树它的递归序列是一定的,导致其前中后序不同的原因只不过是访问节 ...

  5. c语言中二叉树中总结点,C语言二叉树的三种遍历方式的实现及原理

    二叉树遍历分为三种:前序.中序.后序,其中序遍历最为重要.为啥叫这个名字?是根据根节点的顺序命名的. 比如上图正常的一个满节点,A:根节点.B:左节点.C:右节点,前序顺序是ABC(根节点排最先,然后 ...

  6. 二叉树----数据结构:二叉树的三种遍历及习题

    二叉树----数据结构:二叉树的三种遍历,利用递归算法. 关于二叉树的遍历,应用非常广泛,不单单是访问打印结点,还可以进行一系列的操作,如赋值.删除.查找.求二叉树的深度等等. 有递归和非递归两种算法 ...

  7. 二叉树的三种遍历方式:前序遍历、中序遍历和后序遍历

    二叉树的三种遍历方式:前序遍历.中序遍历和后序遍历 参考资料: 二叉树.前序遍历.中序遍历.后序遍历 - 蓝海人 - 博客园 (cnblogs.com) 二叉树 - LeetBook - 力扣(Lee ...

  8. c语言二叉树的遍历菜单系统,C语言二叉树的三种遍历方式的实现及原理

    C语言二叉树的三种遍历方式的实现及原理 发布时间:2020-10-03 19:43:57 来源:脚本之家 阅读:63 作者:看雪. 二叉树遍历分为三种:前序.中序.后序,其中序遍历最为重要.为啥叫这个 ...

  9. C语言基本数据结构之二(二叉树的三种遍历,节点数以及深度算法)

    关于二叉树的定义,网上有比较好的介绍,在这里就简单介绍二叉树的一些性质 二叉树的基本性质 1)二叉树的第i层上至多有 2^(i-1)(i ≥1)个结点: 2)深度为 h 的二叉树中至多含有 2^h – ...

  10. 【数据结构】理解二叉树的三种遍历--前序、中序、后序 +层序(简明易懂)

    一.易懂的形象理解 其实从名字就可以很好的理解这三种遍历,我在第二点时候说,但是估计能翻到我的文的同学们之前肯定看过好多类似的了,那咱们换个思路~ 先用我想的一种简单易懂的形象思维理解一下前序.中序. ...

最新文章

  1. 浙江财经大学java试卷_2020年浙江财经大学社会保障考研真题试卷及试题答案,管理学考研试题下载...
  2. C#播放flash动画即swf文件
  3. JavaScript强化教程——jQuery选择器
  4. js中的if与Java中的if_JS中的if和else的用法以及基础语法
  5. uva 1617——Laptop
  6. SpringSecurity + JWT实现单点登录
  7. vue 跳转页面带对象_vue跳转页面的几种方法(推荐)
  8. mysql中的事物处理
  9. 创建oracle管理用户名和密码是什么情况,Oracle创建时默认创建的用户以及密码
  10. 个推的appid是指什么_私人教练要注意胸肌更快增厚的4个方法
  11. 计算机组成原理试题和答案2017,【2017年整理】计算机组成原理试题及答案9.doc...
  12. java 进制转换_Java 进制转换
  13. 【错误率、精度、查准率、查全率和F1度量】详细介绍
  14. 用python来做一个APP | python GUI 基础(实战)
  15. TANGENT_SPACE_ROTATION的解释
  16. HDR视频色调映射算法(之三:Block matching TMO)
  17. Spring AOP中切入点@Pointcut的使用
  18. c#字符串转为json对象与json转对象
  19. webrtc 之 sip trickle ice
  20. linux驱动调试--段错误之栈信息分析

热门文章

  1. GoLang语言多版本管理工具--GVM入门介绍
  2. C# 结合 PInvoke 对接 IP 摄像头的笔记
  3. Android Studio Button背景颜色无法修改
  4. 【Java】判断某值是否在数组中,使用Arrays类
  5. 【Python】字典类型
  6. C语言实例-大小写字母间的转换
  7. 【缓存】redis的基本使用
  8. freecodecamp_关于freeCodeCamp-常见问题
  9. 考研数学三部曲之大话线性代数
  10. 标星7000+,这个 Python 艺术二维码生成器厉害了!