今天给大家带来二叉树的遍历(前序遍历、中序遍历、后序遍历、层次遍历)。Talk is cheap show me the code.
package com.chenli.Tree;
/**
* 二叉树的结点
* @author 陈力
*
*/
@SuppressWarnings("all")
public class BinaryTreeNode {
private Object data;//数据域
private BinaryTreeNode left;//左孩子
private BinaryTreeNode right;//右孩子
//空的构造函数
public BinaryTreeNode() {
super();
}
//构造函数
public BinaryTreeNode(Object data, BinaryTreeNode left, BinaryTreeNode right) {
super();
this.data = data;
this.left = left;
this.right = right;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public BinaryTreeNode getLeft() {
return left;
}
public void setLeft(BinaryTreeNode left) {
this.left = left;
}
public BinaryTreeNode getRight() {
return right;
}
public void setRight(BinaryTreeNode right) {
this.right = right;
}
}
package com.chenli.Tree;
import java.util.*;
/**
* 二叉树的遍历(前序遍历、中序遍历、后序遍历、层次遍历)
* @author 陈力
*
*/
public class BinaryTree {
//前序遍历(递归)
public void preOrder(BinaryTreeNode node){
if(node != null){
System.out.print(node.getData()+" ");//先取出根结点的数据
preOrder(node.getLeft());//遍历左子树
preOrder(node.getRight());//遍历右子树
}
}
//前序遍历(非递归)
public void preOrder2(BinaryTreeNode node){
Stack<BinaryTreeNode> s = new Stack<BinaryTreeNode>();//使用栈来实现
while(true){
while(node != null){
System.out.print(node.getData()+" ");
s.push(node);
node = node.getLeft();//遍历左子树,直到左子树为空为止
}
if(s.isEmpty()){//栈为空,意味着已经遍历完树了,可以退出循环了。
break;
}
node = s.pop();
node = node.getRight();
}
}
//中序遍历(递归)
public void inOrder(BinaryTreeNode node){
if(node != null){
inOrder(node.getLeft());
System.out.print(node.getData()+" ");
inOrder(node.getRight());
}
}
//中序遍历(非递归)
public void inOrder2(BinaryTreeNode node){
Stack<BinaryTreeNode> s = new Stack<BinaryTreeNode>();//使用栈来实现
while(true){
while(node != null){
s.push(node);
node = node.getLeft();
}
if(s.isEmpty()){//栈为空,意味着已经遍历完树了,可以退出循环了。
break;
}
node = s.pop();
System.out.print(node.getData()+" ");
node = node.getRight();
}
}
//后序遍历(递归)
public void postOrder(BinaryTreeNode node){
if(node != null){
postOrder(node.getLeft());
postOrder(node.getRight());
System.out.print(node.getData()+" ");
}
}
/**
* 后序遍历(非递归)
* 对于任一结点P,将其入栈,然后沿其右子树一直往下搜索,直到搜索到没有右孩子的结点,
* 将他们逐一入栈。(为什么先将右孩子入栈?因为栈的特点是先进后出。)
* 然后搜索左子树,将其入栈。
* 最后将根结点入栈。
* 设计双栈的目的是一个栈是存储结点,另一个栈是记录结点。
*
* @param 陈力
*/
public void postOrder2(BinaryTreeNode node){
Stack<BinaryTreeNode> stack = new Stack<BinaryTreeNode>();//记录结点
Stack<BinaryTreeNode> output = new Stack<BinaryTreeNode>();//存储结点
while(node != null || !stack.isEmpty()){//结点不为空,或者记录结点的栈不为空时,说明树还没遍历完
if(node != null){
stack.push(node);//存进记录结点栈,到时要取出来
output.push(node);//存进存储结点栈
node = node.getRight();
}else{
node = stack.pop();//取出记录结点栈的栈顶元素,看它是否有左子树。
node = node.getLeft();
}
}
while(!output.isEmpty()){//遍历存储结点,把数据取出来。
node = output.pop();
System.out.print(node.getData()+" ");
}
}
//层次遍历
public void level(BinaryTreeNode node){
BinaryTreeNode temp;//定义一个临时结点
//用队列的结构来实现(先进先出)
Queue<BinaryTreeNode> queue = new LinkedList<BinaryTreeNode>();
queue.offer(node);//先把第一元素存进来,即根结点。
while(!queue.isEmpty()){//遍历队列,一边取出一边存储
temp = queue.poll();
System.out.print(temp.getData()+" ");
if(temp.getLeft()!=null){
queue.offer(temp.getLeft());
}
if(temp.getRight()!=null){
queue.offer(temp.getRight());
}
}
}
}
package com.chenli.Tree;
/**
* 测试数据
* @author 陈力
*
*/
public class BinaryTreeDemo {
public static void main(String[] args) {
BinaryTreeNode node10 = new BinaryTreeNode(10, null, null);
BinaryTreeNode node9 = new BinaryTreeNode(9, null, null);
BinaryTreeNode node8 = new BinaryTreeNode(8, null, null);
BinaryTreeNode node7 = new BinaryTreeNode(7, null, null);
BinaryTreeNode node6 = new BinaryTreeNode(6, null, null);
BinaryTreeNode node5 = new BinaryTreeNode(5, node9, node10);
BinaryTreeNode node4 = new BinaryTreeNode(4, node7, node8);
BinaryTreeNode node3 = new BinaryTreeNode(3, node5, node6);
BinaryTreeNode node2 = new BinaryTreeNode(2, node4, null);
BinaryTreeNode node1 = new BinaryTreeNode(1, node2, node3);
BinaryTree bt = new BinaryTree();
//前序遍历(递归)
System.out.println("***前序遍历(递归)***");
bt.preOrder(node1);
System.out.println();
//前序遍历(非递归)
System.out.println("***前序遍历(非递归)***");
bt.preOrder2(node1);
System.out.println();
//中序遍历(递归)
System.out.println("***中序遍历(递归)***");
bt.inOrder(node1);
System.out.println();
//中序遍历(非递归)
System.out.println("***中序遍历(非递归)***");
bt.inOrder2(node1);
System.out.println();
//后序遍历(递归)
System.out.println("***后序遍历(递归)***");
bt.postOrder(node1);
System.out.println();
//后序遍历(非递归)
System.out.println("***后序遍历(非递归)***");
bt.postOrder2(node1);
System.out.println();
//层次遍历
System.out.println("***层次遍历***");
bt.level(node1);
System.out.println();
}
}