在上一篇博客中,实现了Java中二叉树的四种遍历方式的递归实现,接下来,在此实现Java中非递归实现二叉树的前序、中序、后序、层序遍历,在非递归实现中,借助了栈来帮助实现遍历。前序和中序比较类似,也简单一些,但是后序遍历需要两个栈来进行辅助,稍微复杂一些,层序遍历中借助了一个队列来进行实现。

  同样是那棵二叉树

  • 前序遍历:4 2 1 3 6 5 7 8 10

  • 中序遍历:1 2 3 4 5 6 7 8 10

  • 后序遍历:1 3 2 5 10 8 7 6 4

  • 层序遍历:4 2 6 1 3 5 7 8 10

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack; public class Tree<AnyType extends Comparable<? super AnyType>>
{
private static class BinaryNode<AnyType>
{
BinaryNode(AnyType theElement)
{
this(theElement, null, null);
} BinaryNode(AnyType theElement, BinaryNode<AnyType> lt, BinaryNode<AnyType> rt)
{
element = theElement;
left = lt;
right = rt;
} AnyType element;
BinaryNode<AnyType> left;
BinaryNode<AnyType> right;
} private BinaryNode<AnyType> root; public void insert(AnyType x)
{
root = insert(x, root);
} public boolean isEmpty()
{
return root == null;
} private BinaryNode<AnyType> insert(AnyType x, BinaryNode<AnyType> t)
{
if(t == null)
{
return new BinaryNode<>(x, null, null);
} int compareResult = x.compareTo(t.element); if(compareResult < 0)
{
t.left = insert(x, t.left);
}
else if(compareResult > 0)
{
t.right = insert(x, t.right);
}
else
{
;
} return t;
} /**
* 前序遍历
* 递归
*/
public void preOrder(BinaryNode<AnyType> Node)
{
if (Node != null)
{
System.out.print(Node.element + " ");
preOrder(Node.left);
preOrder(Node.right);
}
} /**
* 中序遍历
* 递归
*/
public void midOrder(BinaryNode<AnyType> Node)
{
if (Node != null)
{
midOrder(Node.left);
System.out.print(Node.element + " ");
midOrder(Node.right);
}
} /**
* 后序遍历
* 递归
*/
public void posOrder(BinaryNode<AnyType> Node)
{
if (Node != null)
{
posOrder(Node.left);
posOrder(Node.right);
System.out.print(Node.element + " ");
}
} /*
* 层序遍历
* 递归
*/
public void levelOrder(BinaryNode<AnyType> Node) {
if (Node == null) {
return;
} int depth = depth(Node); for (int i = 1; i <= depth; i++) {
levelOrder(Node, i);
}
} private void levelOrder(BinaryNode<AnyType> Node, int level) {
if (Node == null || level < 1) {
return;
} if (level == 1) {
System.out.print(Node.element + " ");
return;
} // 左子树
levelOrder(Node.left, level - 1); // 右子树
levelOrder(Node.right, level - 1);
} public int depth(BinaryNode<AnyType> Node) {
if (Node == null) {
return 0;
} int l = depth(Node.left);
int r = depth(Node.right);
if (l > r) {
return l + 1;
} else {
return r + 1;
}
} /**
* 前序遍历
* 非递归
*/
public void preOrder1(BinaryNode<AnyType> Node)
{
Stack<BinaryNode> stack = new Stack<>();
while(Node != null || !stack.empty())
{
while(Node != null)
{
System.out.print(Node.element + " ");
stack.push(Node);
Node = Node.left;
}
if(!stack.empty())
{
Node = stack.pop();
Node = Node.right;
}
}
} /**
* 中序遍历
* 非递归
*/
public void midOrder1(BinaryNode<AnyType> Node)
{
Stack<BinaryNode> stack = new Stack<>();
while(Node != null || !stack.empty())
{
while (Node != null)
{
stack.push(Node);
Node = Node.left;
}
if(!stack.empty())
{
Node = stack.pop();
System.out.print(Node.element + " ");
Node = Node.right;
}
}
} /**
* 后序遍历
* 非递归
*/
public void posOrder1(BinaryNode<AnyType> Node)
{
Stack<BinaryNode> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
int i = 1;
while(Node != null || !stack1.empty())
{
while (Node != null)
{
stack1.push(Node);
stack2.push(0);
Node = Node.left;
} while(!stack1.empty() && stack2.peek() == i)
{
stack2.pop();
System.out.print(stack1.pop().element + " ");
} if(!stack1.empty())
{
stack2.pop();
stack2.push(1);
Node = stack1.peek();
Node = Node.right;
}
}
} /*
* 层序遍历
* 非递归
*/
public void levelOrder1(BinaryNode<AnyType> Node) {
if (Node == null) {
return;
} BinaryNode<AnyType> binaryNode;
Queue<BinaryNode> queue = new LinkedList<>();
queue.add(Node); while (queue.size() != 0) {
binaryNode = queue.poll(); System.out.print(binaryNode.element + " "); if (binaryNode.left != null) {
queue.offer(binaryNode.left);
}
if (binaryNode.right != null) {
queue.offer(binaryNode.right);
}
}
} public static void main( String[] args )
{
int[] input = {4, 2, 6, 1, 3, 5, 7, 8, 10};
Tree<Integer> tree = new Tree<>();
for(int i = 0; i < input.length; i++)
{
tree.insert(input[i]);
}
System.out.print("递归前序遍历 :");
tree.preOrder(tree.root);
System.out.print("\n非递归前序遍历:");
tree.preOrder1(tree.root);
System.out.print("\n递归中序遍历 :");
tree.midOrder(tree.root);
System.out.print("\n非递归中序遍历 :");
tree.midOrder1(tree.root);
System.out.print("\n递归后序遍历 :");
tree.posOrder(tree.root);
System.out.print("\n非递归后序遍历 :");
tree.posOrder1(tree.root);
System.out.print("\n递归层序遍历:");
tree.levelOrder(tree.root);
System.out.print("\n非递归层序遍历 :");
tree.levelOrder1(tree.root);
}
}

  在以上代码中,preOrder1、midOrder1、posOrder1、levelOrder1四个函数,分别代表了非递归实现的二叉树前序、中序、后序、层序遍历遍历。

Java实现二叉树的前序、中序、后序遍历(非递归方法)的更多相关文章

  1. Java 重建二叉树 根据前序中序重建二叉树

    题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2, ...

  2. 分别求二叉树前、中、后序的第k个节点

    一.求二叉树的前序遍历中的第k个节点 //求先序遍历中的第k个节点的值 ; elemType preNode(BTNode *root,int k){ if(root==NULL) return ' ...

  3. 【LeetCode】二叉搜索树的前序,中序,后续遍历非递归方法

    前序遍历 public List<Integer> preorderTraversal(TreeNode root) { ArrayList<Integer> list = n ...

  4. 算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序/中序/后序

    接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public ...

  5. 二叉树 遍历 先序 中序 后序 深度 广度 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  6. 前序+中序->后序 中序+后序->前序

    前序+中序->后序 #include <bits/stdc++.h> using namespace std; struct node { char elem; node* l; n ...

  7. SDUT OJ 数据结构实验之二叉树八:(中序后序)求二叉树的深度

    数据结构实验之二叉树八:(中序后序)求二叉树的深度 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Probl ...

  8. SDUT-2804_数据结构实验之二叉树八:(中序后序)求二叉树的深度

    数据结构实验之二叉树八:(中序后序)求二叉树的深度 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 已知一颗二叉树的中序 ...

  9. 给出 中序&后序 序列 建树;给出 先序&中序 序列 建树

    已知 中序&后序  建立二叉树: SDUT 1489 Description  已知一棵二叉树的中序遍历和后序遍历,求二叉树的先序遍历 Input  输入数据有多组,第一行是一个整数t (t& ...

  10. 【C&数据结构】---关于链表结构的前序插入和后序插入

    刷LeetCode题目,需要用到链表的知识,忽然发现自己对于链表的插入已经忘得差不多了,以前总觉得理解了记住了,但是发现真的好记性不如烂笔头,每一次得学习没有总结输出,基本等于没有学习.连复盘得机会都 ...

随机推荐

  1. android MessageQueue入门

    接触安卓几年了.但是感觉一直不是很明白,东西太多了.反过来说就是自己太菜了.很多东西其实都是模凌两可,不熟悉,很多知识点都是知道一点,最多大家都这样用.没问题,事件长了也一直这样用的.但是有个问题,安 ...

  2. 16、手把手教你Extjs5(十六)Grid金额字段单位MVVM方式的选择

    这一节来完成Grid中的金额字段的金额单位的转换.转换旰使用MVVM特性,总体上和控制菜单的几种模式类似.首先在目录app/view/main/menu下建立文件Monetary.js,用于放金额单位 ...

  3. Xcode--Alcatraz来管理Xcode插件

    简介 Alcatraz是一个帮你管理Xcode插件.模版以及颜色配置的工具.它可以直接集成到Xcode的图形界面中,让你感觉就像在使用Xcode自带的功能一样. 安装和删除 使用如下的命令行来安装Al ...

  4. css(四)-- 盒子模型和定位

    盒子模型: 盒子模型就是把一个html边框比作成了一个盒子的边框,盒子模型要做用于操作数据与边框之间的距离或者 是边框与边框之间的距离. 盒子模型主要是用于操作内边距(padding)与外边距(mar ...

  5. [Angular Tutorial] 13 -REST and Custom Services

    在这一步中,我们将会改变我们获取数据的方式. ·我们定义一个代表RESTful客户端的自定义服务.使用这个客户端,我们可以用一种更简单的方法向服务端请求数据,而不用处理更底层的$httpAPI,HTT ...

  6. APK的反编译

    有秘密的地方就有见不得光的东西,我讨厌这些,所以对于某一个XX圈APP极其反感,感觉就像一个色情网站 一.ApkTool的使用 看了几个教程,自己下载的好像总是不完整,下载包解压后一个没有aapt.e ...

  7. constrain to margins

    如果你点了constrain to margins,左右会有8个点的空挡,而是从8个点后开始计算约束,而没有点时,已屏幕的0点开始计算.

  8. perl访问数组中变量

    数组一个是存储标量值的无序列表变量. 数组变量以 @ 开头.访问数组元素使用 $ + 变量名称 + [索引值] 格式来读取,实例如下: #!/usr/bin/perl @names = (" ...

  9. Android应用性能优化方案

    1.避免创建不必要的对象 2.如果方法用不到成员变量,可以把方法声明为静态(static),这样性能会提高百分之十五到百分之二十 3.避免使用get/set存取字段,可以把字段声明为public直接访 ...

  10. Spring的IOC原理[通俗解释一下]

    Spring的IOC原理[通俗解释一下] 1. IoC理论的背景我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 图 ...