package research;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
/**
* 二叉树的多种遍历:先序遍历、中序遍历、后序遍历、层次遍历、深度优先遍历、广度优先遍历
*
* @author Sam
*
*/
public class BinaryTree {
public static void main(String[] args) {
Node root = Factory.create(4);
System.out.print("先序遍历:");
NLR(root);
System.out.println();
System.out.print("中序遍历:");
LNR(root);
System.out.println();
System.out.print("后序遍历:");
LRN(root);
System.out.println();
System.out.print("层次遍历:");
Level(root);
System.out.println();
System.out.print("深度优先遍历:");
depthFirstSearch(root);
System.out.println();
System.out.print("广度优先遍历:");
breadthFirstSearch(root);
}
/**
* 先序遍历:首先访问根,再先序遍历左(右)子树,最后先序遍历右(左)子树。
*
* @param n
*/
static void NLR(Node n) {
if (null == n) {
return;
}
System.out.print(n);
NLR(n.getLeft());
NLR(n.getRight());
}
/**
* 中序遍历:首先中序遍历左(右)子树,再访问根,最后中序遍历右(左)子树。
*
* @param n
*/
static void LNR(Node n) {
if (null == n) {
return;
}
LNR(n.getLeft());
System.out.print(n);
LNR(n.getRight());
}
/**
* 后序遍历:首先后序遍历左(右)子树,再后序遍历右(左)子树,最后访问根。
*
* @param n
*/
static void LRN(Node n) {
if (null == n) {
return;
}
LRN(n.getLeft());
LRN(n.getRight());
System.out.print(n);
}
/**
* 层次遍历:即按照层次访问,通常用队列来做。访问根,访问子女,再访问子女的子女(越往后的层次越低)(两个子女的级别相同).
* Queue1与Queue2交互存储二叉树的每一层
*
* @param n
*/
static void Level(Node n) {
Queue<Node> queue1 = new LinkedList<Node>();
Queue<Node> queue2 = new LinkedList<Node>();
queue1.add(n);
while (!queue1.isEmpty() || !queue2.isEmpty()) {
System.out.println();
while (!queue1.isEmpty()) {
Node curNode = queue1.poll();
System.out.print(curNode);
if (null != curNode.getLeft()) {
queue2.add(curNode.getLeft());
}
if (null != curNode.getRight()) {
queue2.add(curNode.getRight());
}
}
System.out.println();
while (!queue2.isEmpty()) {
Node curNode = queue2.poll();
System.out.print(curNode);
if (null != curNode.getLeft()) {
queue1.add(curNode.getLeft());
}
if (null != curNode.getRight()) {
queue1.add(curNode.getRight());
}
}
}
}
/**
* 深度优先遍历
*
* @param root
*/
static void depthFirstSearch(Node root) {
Stack<Node> stack = new Stack<Node>();
stack.push(root);
Node node;
while (!stack.empty()) {
node = stack.pop();
System.out.print(node);
if (null != node.getRight()) {
stack.push(node.getRight());// 先将右子树压栈
}
if (null != node.getLeft()) {
stack.push(node.getLeft());// 再将左子树压栈
}
}
}
/**
* 广度优先遍历
*
* @param root
*/
static void breadthFirstSearch(Node root) {
Queue<Node> queue = new LinkedList<Node>();
queue.add(root);
Node node;
while (!queue.isEmpty()) {
node = queue.poll();
System.out.print(node);
if (null != node.getLeft()) {
queue.add(node.getLeft());// 先将左子树入队
}
if (null != node.getRight()) {
queue.add(node.getRight());// 再将右子树入队
}
}
}
}
class Node {
private Object data;
private Node left;
private Node right;
public Node() {
}
public Node(Object o) {
data = o;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
@Override
public String toString() {
return null == data ? "" : String.format(" %s ", data.toString());
}
}
/**
* (1)空二叉树<br>
* (2)只有一个根结点的二叉树<br>
* (3)只有左子树<br>
* (4)只有右子树<br>
* (5)完全二叉树。
*
* @author Sam
*
*/
class Factory {
public static Node create(int deep) {
return create(1, 1, deep);
}
private static Node create(int data, int h, int deep) {
Node parent = new Node(data);
if (h < deep) {
int next = h + 1;
parent.setLeft(create(data * 2, next, deep));
parent.setRight(create(data * 2 + 1, next, deep));
}
return parent;
}
}
运行结果:
先序遍历: 1 2 4 8 9 5 10 11 3 6 12 13 7 14 15
中序遍历: 8 4 9 2 10 5 11 1 12 6 13 3 14 7 15
后序遍历: 8 9 4 10 11 5 2 12 13 6 14 15 7 3 1
层次遍历:
1
2 3
4 5 6 7
8 9 10 11 12 13 14 15
深度优先遍历: 1 2 4 8 9 5 10 11 3 6 12 13 7 14 15
广度优先遍历: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15