簡單介紹一下:
前序遍歷:父節點--左孩子節點--右孩子節點
中序遍歷:左孩子節點--父節點--右孩子節點
後序遍歷:左孩子節點--右孩子節點--父節點
前中後指的是父節點在整個樹的處理過程中次序。
代碼:
實體類:
/**
* @author yinglala
*/
public class BinaryTree {
private int data;
private BinaryTree lchild;
private BinaryTree rchild;
public BinaryTree(int data) {
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public BinaryTree getLchild() {
return lchild;
}
public void setLchild(BinaryTree lchild) {
this.lchild = lchild;
}
public BinaryTree getRchild() {
return rchild;
}
public void setRchild(BinaryTree rchild) {
this.rchild = rchild;
}
}
遍歷方法:
import java.util.Stack;
/**
* @author yinglala
*/
public class BinaryTreeOrder {
//前序遍歷
private static void preOrder(BinaryTree t){
if(t == null){
return;
}
System.out.print(t.getData() + " ");
preOrder(t.getLchild());
preOrder(t.getRchild());
}
//中序遍歷
private static void inOrder(BinaryTree t){
if (t == null){
return;
}
inOrder(t.getLchild());
System.out.print(t.getData() + " ");
inOrder(t.getRchild());
}
//後續遍歷
private static void postOrder(BinaryTree t){
if(t == null){
return;
}
postOrder(t.getLchild());
postOrder(t.getRchild());
System.out.print(t.getData() + " ");
}
//非遞歸版本
//非遞歸前序遍歷
private static void nonRecursivePreOrder(BinaryTree t){
if( t == null){
return;
}
Stack<BinaryTree> stack = new Stack();
stack.push(t);
//棧不爲空 進行彈出等操作
while (stack != null && stack.size() != 0){
//彈出棧頂元素
BinaryTree tmpTree = stack.pop();
//打印
System.out.print(tmpTree.getData() + " ");
//若tmpTree同時存在左子樹和右子樹 先對右子樹進行壓棧 再對左子樹進行壓棧
//根據棧的特性 左子樹位於棧頂 先彈出左子樹 再彈出右子樹
if(tmpTree.getRchild() != null){
stack.push(tmpTree.getRchild());
}
if(tmpTree.getLchild() != null){
stack.push(tmpTree.getLchild());
}
}
}
//非遞歸版本中序遍歷
private static void nonRecursiveInOrder(BinaryTree t){
if(t == null){
return;
}
Stack<BinaryTree> stack = new Stack();
stack.push(t);
//初始化輔助節點P
BinaryTree p = t;
while(stack != null && stack.size() != 0){
//如果左孩子不爲空 先壓棧
if(p != null && p.getLchild() != null){
stack.push(p.getLchild());
p = p.getLchild();
}else {
//彈出棧頂元素
p = stack.pop();
//打印
System.out.print(p.getData() + " ");
if(p.getRchild() != null){
stack.push(p.getRchild());
p = p.getRchild();
}else {
//p = stack.pop(); p已經訪問過了 將p設置爲空
p = null;
}
}
}
}
//非遞歸版本後序遍歷
private static void nonRecursivePostOrder(BinaryTree t){
if(t == null){
return;
}
Stack<BinaryTree> stack = new Stack();
stack.push(t);
BinaryTree p = t;
BinaryTree tVisit = null;
while(stack != null && stack.size() != 0){
//如果左孩子不爲空 先壓棧
if(p != null && p.getLchild() != null){
stack.push(p.getLchild());
p = p.getLchild();
}else{
p = stack.peek();//獲取棧頂元素 並保證p不爲空
//若沒有右孩子,或者右孩子已經被訪問過
if(p.getRchild() == null || p.getRchild() == tVisit){
//打印
System.out.print(p.getData() + " ");
//標明上個被訪問的節點 防止在回溯的過程中無限訪問右孩子節點
tVisit = p;
p = null;
//棧頂元素及其孩子節點已訪問 出棧
stack.pop();
}else{
stack.push(p.getRchild());
p = p.getRchild();
}
}
}
}
public static void main(String[] args){
BinaryTree root = new BinaryTree(1);
BinaryTree second = new BinaryTree(2);
BinaryTree three = new BinaryTree(3);
BinaryTree four = new BinaryTree(4);
BinaryTree five = new BinaryTree(5);
BinaryTree six = new BinaryTree(6);
BinaryTree seven = new BinaryTree(7);
root.setLchild(second);
root.setRchild(three);
second.setLchild(four);
second.setRchild(five);
three.setLchild(six);
three.setRchild(seven);
System.out.println("遞歸先序遍歷:");
preOrder(root);
System.out.println();
System.out.println("遞歸中序遍歷:");
inOrder(root);
System.out.println();
System.out.println("遞歸後序遍歷:");
postOrder(root);
System.out.println();
System.out.println("非遞歸先序遍歷:");
nonRecursivePreOrder(root);
System.out.println();
System.out.println("非遞歸中序遍歷:");
nonRecursiveInOrder(root);
System.out.println();
System.out.println("非遞歸後序遍歷:");
nonRecursivePostOrder(root);
}
}
執行結果:
遞歸先序遍歷:
1 2 4 5 3 6 7
遞歸中序遍歷:
4 2 5 1 6 3 7
遞歸後序遍歷:
4 5 2 6 7 3 1
非遞歸先序遍歷:
1 2 4 5 3 6 7
非遞歸中序遍歷:
4 2 5 1 6 3 7
非遞歸後序遍歷:
4 5 2 6 7 3 1
Process finished with exit code 0