import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Stack; /**
*
* @author kerryfish
* JAVA实现二叉树的先序、中序、后序、层序遍历
* 递归和非递归版本
*
*/ class Node{
public int value;
public Node left;
public Node right;
public Node(int v){
this.value=v;
this.left=null;
this.right=null;
} }
class BinaryTreeTraversal {
/**
* @param root 树根节点
* 递归先序遍历
*/
public static void preOrderRec(Node root){
if(root!=null){
System.out.println(root.value);
preOrderRec(root.left);
preOrderRec(root.right);
}
}
/**
* @param root 树根节点
* 递归中序遍历
*/
public static void inOrderRec(Node root){
if(root!=null){
preOrderRec(root.left);
System.out.println(root.value);
preOrderRec(root.right);
}
}
/**
* @param root 树根节点
* 递归后序遍历
*/
public static void postOrderRec(Node root){
if(root!=null){
preOrderRec(root.left);
preOrderRec(root.right);
System.out.println(root.value);
}
}
/**
*
* @param root 树根节点
* 利用栈实现循环先序遍历二叉树
* 这种实现类似于图的深度优先遍历(DFS)
* 维护一个栈,将根节点入栈,然后只要栈不为空,出栈并访问,接着依次将访问节点的右节点、左节点入栈。
* 这种方式应该是对先序遍历的一种特殊实现(看上去简单明了),但是不具备很好的扩展性,在中序和后序方式中不适用
*/
public static void preOrderStack_1(Node root){
if(root==null)return;
Stack<Node> s=new Stack<Node>();
s.push(root);
while(!s.isEmpty()){
Node temp=s.pop();
System.out.println(temp.value);
if(temp.right!=null) s.push(temp.right);
if(temp.left!=null) s.push(temp.left);
}
}
/**
*
* @param root 树的根节点
* 利用栈模拟递归过程实现循环先序遍历二叉树
* 这种方式具备扩展性,它模拟递归的过程,将左子树点不断的压入栈,直到null,然后处理栈顶节点的右子树
*/
public static void preOrderStack_2(Node root){
if(root==null)return;
Stack<Node> s=new Stack<Node>();
while(root!=null||!s.isEmpty()){
while(root!=null){
System.out.println(root.value);
s.push(root);//先访问再入栈
root=root.left;
}
root=s.pop();
root=root.right;//如果是null,出栈并处理右子树
}
}
/**
*
* @param root 树根节点
* 利用栈模拟递归过程实现循环中序遍历二叉树
* 思想和上面的preOrderStack_2相同,只是访问的时间是在左子树都处理完直到null的时候出栈并访问。
*/
public static void inOrderStack(Node root){
if(root==null)return;
Stack<Node> s=new Stack<Node>();
while(root!=null||!s.isEmpty()){
while(root!=null){
s.push(root);//先访问再入栈
root=root.left;
}
root=s.pop();
System.out.println(root.value);
root=root.right;//如果是null,出栈并处理右子树
}
}
/**
*
* @param root 树根节点
* 后序遍历不同于先序和中序,它是要先处理完左右子树,然后再处理根(回溯),所以需要一个记录哪些节点已经被访问的结构(可以在树结构里面加一个标记),这里可以用map实现
*/
public static void postOrderStack(Node root){
if(root==null)return;
Stack<Node> s=new Stack<Node>();
Map<Node,Boolean> map=new HashMap<Node,Boolean>();
s.push(root);
while(!s.isEmpty()){
Node temp=s.peek();
if(temp.left!=null&&!map.containsKey(temp.left)){
temp=temp.left;
while(temp!=null){
if(map.containsKey(temp))break;
else s.push(temp);
temp=temp.left;
}
continue;
}
if(temp.right!=null&&!map.containsKey(temp.right)){
s.push(temp.right);
continue;
}
Node t=s.pop();
map.put(t,true);
System.out.println(t.value);
}
}
/**
*
* @param root 树根节点
* 层序遍历二叉树,用队列实现,先将根节点入队列,只要队列不为空,然后出队列,并访问,接着讲访问节点的左右子树依次入队列
*/
public static void levelTravel(Node root){
if(root==null)return;
Queue<Node> q=new LinkedList<Node>();
q.add(root);
while(!q.isEmpty()){
Node temp = q.poll();
System.out.println(temp.value);
if(temp.left!=null)q.add(temp.left);
if(temp.right!=null)q.add(temp.right);
}
}
}

  

JAVA下实现二叉树的先序、中序、后序、层序遍历(递归和循环)的更多相关文章

  1. 二叉树(前序,中序,后序,层序)遍历递归与循环的python实现

    二叉树的遍历是在面试使比较常见的项目了.对于二叉树的前中后层序遍历,每种遍历都可以递归和循环两种实现方法,且每种遍历的递归实现都比循环实现要简洁.下面做一个小结. 一.中序遍历 前中后序三种遍历方法对 ...

  2. LeetCode:二叉树的前、中、后序遍历

    描述: ------------------------------------------------------- 前序遍历: Given a binary tree, return the pr ...

  3. leetcode(144,94,145,102)中迭代版的二叉树的前、中、后、层级遍历

    //前序遍历class Solution{ public: vector<int> preorderTraversal(TreeNode *root){ vector<int> ...

  4. [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)

    Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOEx ...

  5. [Java]算术表达式求值之一(中序表达式转后序表达式方案)

    第二版请见:https://www.cnblogs.com/xiandedanteng/p/11451359.html 入口类,这个类的主要用途是粗筛用户输入的算术表达式: package com.h ...

  6. 已知树的前序、中序,求后序的java实现&已知树的后序、中序,求前序的java实现

    public class Order { int findPosInInOrder(String str,String in,int position){ char c = str.charAt(po ...

  7. DS Tree 已知先序、中序 => 建树 => 求后序

    参考:二叉树--前序和中序得到后序 思路历程: 在最初敲的时候,经常会弄混preorder和midorder的元素位置.大体的思路就是在preorder中找到根节点(根节点在序列的左边),然后在mid ...

  8. TZOJ 3209 后序遍历(已知中序前序求后序)

    描述 在数据结构中,遍历是二叉树最重要的操作之一.所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问. 这里给出三种遍历算法. 1.中序遍历的递归算法定义:  ...

  9. hdu1710-Binary Tree Traversals (由二叉树的先序序列和中序序列求后序序列)

    http://acm.hdu.edu.cn/showproblem.php?pid=1710 Binary Tree Traversals Time Limit: 1000/1000 MS (Java ...

随机推荐

  1. java中复制对象通过反射或序列化

    在使用缓存读取数据后修改发现缓存被修改.于是找了下复制对象的方法. 关于对象克隆 按我的理解,对象是包含引用+数据.通常变量复制都是将引用传递过去.比如: Person p1 = new Person ...

  2. 性能调优:理解Set Statistics IO输出

    性能调优是DBA的重要工作之一.很多人会带着各种性能上的问题来问我们.我们需要通过SQL Server知识来处理这些问题.经常被问到的一个问题是:早上这个存储过程运行时间还是可以的,但到了晚上就很慢很 ...

  3. MVC之前的那点事儿系列(6):动态注册HttpModule

    文章内容 通过前面的章节,我们知道HttpApplication在初始化的时候会初始化所有配置文件里注册的HttpModules,那么有一个疑问,能否初始化之前动态加载HttpModule,而不是只从 ...

  4. 用redux完成事务清单

    今天再来一个例子,我们从组件开始. App.js import React, { PropTypes } from 'react' import { bindActionCreators } from ...

  5. Razor练习1

    学习ASP.NET MVC, Razor语法必须掌握,这篇学习: Razor code blocks are enclosed in @{ ... }Inline expressions (varia ...

  6. Mysql日期统计函数简介

    NOW() 返回当前的日期和时间 CURDATE() 返回当前的日期 CURTIME() 返回当前的时间 DATE() 提取日期或日期/时间表达式的日期部分 EXTRACT() 返回日期/时间按的单独 ...

  7. 如何使用C#创建WebService

    使用C#创建WebService,服务端的webservice是必须,中间的soap,Xml我们不用去关心.下面是使用C#创建WebService的简单介绍. AD:51CTO技术沙龙 | 赋予APP ...

  8. 炉石传说 C# 开发笔记(BS上线尝试)

    昨天买了一个月的1G 1核的服务器,由于不是新用户,所以没有享受到阿里的6个月免费的优惠. (阿里脑残,为什么不对于续费或者升级免费呢?) 在服务器的通讯上面已经OK了,完全绕过了ASP.NET,就是 ...

  9. .NET使用ZXing.NET生成中间带图片的二维码

    很久之前就有写这样的代码了,只是一直没记录下来,偶然想写成博客. 把之前的代码封装成函数,以方便理解以及调用. 基于开源的 ZXing.NET 组件,代码如下: 先添加对ZXing.NET的引用,然后 ...

  10. 使用PDF.JS在线查看PDF

    过程简单粗暴. 第一步:下载源码https://github.com/mozilla/pdf.js 第二步:将源码拷贝进项目中,可以新建一个PDFShow文件夹存放代码 第三步:修改viewer.js ...