JAVA下实现二叉树的先序、中序、后序、层序遍历(递归和循环)
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下实现二叉树的先序、中序、后序、层序遍历(递归和循环)的更多相关文章
- 二叉树(前序,中序,后序,层序)遍历递归与循环的python实现
二叉树的遍历是在面试使比较常见的项目了.对于二叉树的前中后层序遍历,每种遍历都可以递归和循环两种实现方法,且每种遍历的递归实现都比循环实现要简洁.下面做一个小结. 一.中序遍历 前中后序三种遍历方法对 ...
- LeetCode:二叉树的前、中、后序遍历
描述: ------------------------------------------------------- 前序遍历: Given a binary tree, return the pr ...
- leetcode(144,94,145,102)中迭代版的二叉树的前、中、后、层级遍历
//前序遍历class Solution{ public: vector<int> preorderTraversal(TreeNode *root){ vector<int> ...
- [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)
Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOEx ...
- [Java]算术表达式求值之一(中序表达式转后序表达式方案)
第二版请见:https://www.cnblogs.com/xiandedanteng/p/11451359.html 入口类,这个类的主要用途是粗筛用户输入的算术表达式: package com.h ...
- 已知树的前序、中序,求后序的java实现&已知树的后序、中序,求前序的java实现
public class Order { int findPosInInOrder(String str,String in,int position){ char c = str.charAt(po ...
- DS Tree 已知先序、中序 => 建树 => 求后序
参考:二叉树--前序和中序得到后序 思路历程: 在最初敲的时候,经常会弄混preorder和midorder的元素位置.大体的思路就是在preorder中找到根节点(根节点在序列的左边),然后在mid ...
- TZOJ 3209 后序遍历(已知中序前序求后序)
描述 在数据结构中,遍历是二叉树最重要的操作之一.所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问. 这里给出三种遍历算法. 1.中序遍历的递归算法定义: ...
- hdu1710-Binary Tree Traversals (由二叉树的先序序列和中序序列求后序序列)
http://acm.hdu.edu.cn/showproblem.php?pid=1710 Binary Tree Traversals Time Limit: 1000/1000 MS (Java ...
随机推荐
- 在Elasticsearch中查询Term Vectors词条向量信息
这篇文章有点深度,可能需要一些Lucene或者全文检索的背景.由于我也很久没有看过Lucene了,有些地方理解的不对还请多多指正. 更多内容还请参考整理的ELK教程 关于Term Vectors 额, ...
- C# 根据自定义线程定时器 生成随机订单
这个源之于一个朋友问我的一个问题,他说他们的需求是在一天之内随机抽取数据生成订单,还不能让客户看出来. 随机生成的订单还分概率抽取不一定的状态值,那么根据我之前写的定时器线程执行器,我们设计需要一个定 ...
- GitHub一代:我们都是开源控
我们是新的GitHub一代?GitHub塑造了新式开源文化?嗯,看看十几年开源控.Getable CTO Mikeal Rogers 是怎么说的吧: GitHub本来想做一个开源软件协作平台,结果做着 ...
- LeetCode - Balanced Binary Tree
题目: Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced bin ...
- jquery.form.js实现异步上传
前台页面 @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewpor ...
- 常用的一些SQL语句整理,也许有你想要的。
本篇文章是对一些常用的sql语句进行了总结与分析,需要的朋友参考下,也许会有你需要的. 1.SQL行列转换 问题:假设有张学生成绩表(tb)如下:姓名 课程 分数张三 语文 74张三 数学 83张三 ...
- .Net(C#)最简单的邮件发送案例
一.序言 刚开始接触邮件发送功能的时候,在网上找的资料都挺复杂的!对于新手入门有点难(至少对于本人来说,第一次接触的时候确实不容易).这里就写一段简单的邮箱发送代码,备忘,也给新手一个参考(相关类的字 ...
- net发布的dll方法和类显示注释信息(字段说明信息)[图解]
自己发布的dll添加的另一个项目中突然没有字段说明信息了,给使用带来了很多的不便,原因是为了跨项目引用,所以导致不显示注释信息的,一下是解决这个问题的方法. 在要发布(被引用)的项目上右键 => ...
- 六个创建模式之建造者模式(Builder Pattern)
定义: 将一个复杂的对象的构建与它的表示分类,使得同样的构建过程可以创建不同的表示.建造者模式一步步地创建一个复杂对象,但用户仅需指定对象的类型和内容,不需要关心各个部分之间的关联关系. 结构图: B ...
- 正确的前端传后台json方式
DEMO: var data=JSON.stringify({"page": {"pagenow": 1,"pagesize": 20},& ...