目錄:
- 二叉樹深度
- 二叉樹前序遍歷
- 遞歸實現
- 二種非遞歸實現
- 二叉樹中序遍歷:
- 遞歸實現
- 非遞歸實現
- 二叉樹後序遍歷:
- 遞歸實現
- 非遞歸實現
- 二叉樹層次遍歷
- 二叉樹層次創建,創建方法遵循卡特蘭數
import java.util.Queue;
import java.util.Stack;
/*
* ssuchange
*/
public class BinTreeTraversal {
public static final int SIZE = 30;
public static final char NULLNODE = '#';
public static char[] Sequeuce =newchar[100];
public static int SeqCount;
static class Node {
public Node(char ch) {
val = ch;
left = null;
right = null;
}
char val;
Node left;
Node right;
}
public static void main(String[] args) {
System.out.println("Start");
// testTree();
for (int i = 0; i < 26; i++)
catalanCreateBinTree(i);
System.out.println("End");
}
// a
// / \
// b c
// / \ / \
// d e f g
// / /\ / \
// h i j k l
public static void testTree() {
Node a = new Node('a');
Node b = new Node('b');
Node c = new Node('c');
Node d = new Node('d');
Node e = new Node('e');
Node f = new Node('f');
Node g = new Node('g');
Node h = new Node('h');
Node i = new Node('i');
Node j = new Node('j');
Node k = new Node('k');
Node l = new Node('l');
a.left = b;
a.right = c;
b.left = d;
b.right = e;
c.left = f;
c.right = g;
d.left = h;
e.left = i;
e.right = j;
g.left = k;
g.right = l;
try {
testTree(a);
} catch (Exception e1) {
e1.printStackTrace();
}
}
public static void testTree(Node tree)throws Exception {
String rightStr, computeStr;
Println("****************");
Println("Depth:\t" +depthRec(tree));
Println("遞歸前序遍歷");
SeqCount = 0;
preTraRec(tree);
rightStr = getSequence();
Println();
Println("非遞歸前序遍歷");
Println("方法一");
SeqCount = 0;
preTraNoRec1(tree);
computeStr = getSequence();
if (!computeStr.equals(rightStr))
throw new Exception("RightStr isnot equal computeStr!");
Println();
Println("方法二");
SeqCount = 0;
preTraNoRec2(tree);
computeStr = getSequence();
if (!computeStr.equals(rightStr))
throw new Exception("RightStr isnot equal computeStr!");
Println();
Println("遞歸中序遍歷");
SeqCount = 0;
midTraRec(tree);
rightStr = getSequence();
Println();
Println("非遞歸中序遍歷");
SeqCount = 0;
midTraNoRec(tree);
computeStr = getSequence();
if (!computeStr.equals(rightStr))
throw new Exception("RightStr isnot equal computeStr!");
Println();
Println("遞歸後序遍歷");
SeqCount = 0;
postTraRec(tree);
rightStr = getSequence();
Println();
Println("非遞歸後序遍歷");
SeqCount = 0;
postTraNoRec(tree);
computeStr = getSequence();
if (!computeStr.equals(rightStr))
throw new Exception("RightStr isnot equal computeStr!");
Println();
Println("****************");
}
// 求二叉樹深度
public static int depthRec(Node tree) {
if (tree ==null)
return 0;
// 遞歸求解左右子樹深度。
int leftDepth =depthRec(tree.left);
int rightDepth =depthRec(tree.right);
// 取左右子樹中大的加1作爲當前深度。
return (leftDepth > rightDepth ? leftDepth: rightDepth) + 1;
}
// 訪問節點
public static void visit(Node node) {
if (node ==null)
return;
Print(node.val +" ");
Sequeuce[SeqCount++] = node.val;
}
public static String getSequence() {
return new String(Sequeuce, 0,SeqCount);
}
// 前序遍歷遞歸求解
public static void preTraRec(Node tree) {
if (tree ==null)
return;
visit(tree);
preTraRec(tree.left);
preTraRec(tree.right);
}
// 前序遍歷非遞歸求解
// 先訪問當前節點,在不斷向下壓棧找左子樹,最後出棧訪問右子樹,此時,右子樹又成爲一顆單獨子樹
public static void preTraNoRec1(Node tree) {
if (tree ==null)
return;
Node node = tree;
Node[] stack = new Node[SIZE];
int top = 0;
while (node !=null || top > 0) {
while (node !=null) {
// 訪問當前節點
visit(node);
// 記錄當前節點,用於查找當前節點的右子樹
stack[top++] = node;
// 訪問當前節點的左子樹
node = node.left;
}
if (top > 0) {
// 訪問完當前左子樹,出棧訪問右子樹
node = stack[--top].right;
}
}
}
public static void preTraNoRec2(Node tree) {
if (tree ==null)
return;
Node node = tree;
Node[] stack = new Node[SIZE];
int top = 0;
stack[top++] = node;
while (top > 0) {
// 根節點出棧
node = stack[--top];
// 訪問根節點
visit(node);
// 因爲下一次出棧先訪問左子樹,所以先壓棧右子樹,再壓棧左子樹,使得左子樹先出棧
// 右子樹節點壓棧
if (node.right !=null)
stack[top++] = node.right;
// 左子樹節點壓棧
if (node.left !=null)
stack[top++] = node.left;
// 根節點訪問完成後,將左右子樹壓棧,然後根節點丟棄。
}
}
// 中序遍歷遞歸求解
public static void midTraRec(Node tree) {
if (tree ==null)
return;
midTraRec(tree.left);
visit(tree);
midTraRec(tree.right);
}
// 中序遍歷非遞歸求解
// 與前序遍歷非遞歸求解相同,只要改變訪問節點的位置。
public static void midTraNoRec(Node tree) {
if (tree ==null)
return;
Node node = tree;
Node[] stack = new Node[SIZE];
int top = 0;
while (node !=null || top > 0) {
while (node !=null) {
// 記錄當前節點,用於查找當前節點的右子樹
stack[top++] = node;
// 訪問當前節點的左子樹
node = node.left;
}
if (top > 0) {
// 訪問完當前左子樹,出棧訪問根節點
node = stack[--top];
// 訪問根節點
visit(node);
// 訪問右子樹
node = node.right;
}
}
}
// 後序遍歷遞歸求解
public static void postTraRec(Node tree) {
if (tree ==null)
return;
postTraRec(tree.left);
postTraRec(tree.right);
visit(tree);
}
// 後序遍歷非遞歸求解
public static void postTraNoRec(Node tree) {
if (tree ==null)
return;
Node node = tree;
Node[] stackCom = new Node[SIZE];
int topCom = 0;
Node[] stackVis = new Node[SIZE];
int topVis = 0;
stackCom[topCom++] = node;
while (topCom > 0) {
node = stackCom[--topCom];
stackVis[topVis++] = node;
if (node.left !=null)
stackCom[topCom++] = node.left;
if (node.right !=null)
stackCom[topCom++] = node.right;
}
while (topVis > 0) {
visit(stackVis[--topVis]);
}
}
static class Queue<T> {
Object[] queue = new Object[SIZE];
int front = 0;
int rear = 0;
public void enqueue(T t) {
if ((rear + 1) %SIZE ==front) {
try {
thrownew Exception("Queue isfull!");
} catch (Exception e) {
e.printStackTrace();
}
}
queue[rear] = t;
rear = (rear + 1) %SIZE;
}
public T dequeue() {
if (rear ==front) {
try {
thrownew Exception("Queue isempty!");
} catch (Exception e) {
e.printStackTrace();
}
}
T t = (T) queue[front];
front = (front + 1) %SIZE;
return t;
}
public boolean isEmpty() {
returnrear ==front;
}
}
// 層次遍歷
public static void levelTra(Node tree) {
if (tree ==null)
return;
Queue<Node> queue = newQueue<Node>();
queue.enqueue(tree);
while (!queue.isEmpty()) {
Node node = queue.dequeue();
visit(node);
if (node.left !=null)
queue.enqueue(node.left);
if (node.right !=null)
queue.enqueue(node.right);
}
}
// 層次構建二叉樹
public static Node levelCreate(char[] array) {
if (array ==null || array.length == 0)
return null;
int index = 0;
Node tree = null;
if (array[index] ==NULLNODE)
return tree;
Queue<Node> queue = newQueue<Node>();
tree = new Node(array[index]);
index++;
queue.enqueue(tree);
while (!queue.isEmpty() && index <array.length) {
Node node = queue.dequeue();
if (array[index] ==NULLNODE)
node.left = null;
else {
node.left = new Node(array[index]);
queue.enqueue(node.left);
}
index++;
if (array[index] ==NULLNODE)
node.right = null;
else {
node.right = new Node(array[index]);
queue.enqueue(node.right);
}
index++;
}
if (queue.isEmpty() && index == array.length)
return tree;
return null;
}
public static void testBinTree(char[] array) {
// for (int i = 0; i < array.length; i++) {
// Print(array[i]);
// }
// Println();
Node tree = levelCreate(array);
try {
testTree(tree);
} catch (Exception e) {
e.printStackTrace();
}
}
// 卡特蘭數構建二叉樹層次遍歷序列
// 令二叉樹節點總數爲N,有另個孩子的節點數爲a,一個孩子的節點數爲b,沒有孩子的節點爲c。
// 有2a+b+1=n,即除了根節點的所有節點都是其父節點的孩子節點,孩子節點加上根節點構成整個二叉樹;
// 有a+b+c=n,即二叉樹節點由非葉子節點(雙孩子節點、單孩子節點)和葉子節點組成。
// 得b+2c=n+1,即非空節點數爲n的二叉樹有n+1個空節點。
// 非空節點數爲n的二叉樹滿足卡特蘭數的構建原則,推導見卡特蘭數百度百科。
// 非空節點數爲n的二叉樹的層次遍歷序列共有2*n+1個數,最後一個一定爲空節點,前2*n個節點構建原則爲:
// n個1,n個0構成長度爲2*n的序列,任意位置前面和當前位置的1的個數一定大於等於0的個數,1代表非空節點,0代表空節點
//http://www.cppblog.com/MiYu/archive/2010/08/07/122573.html
public static void catalanCreateBinTree(int n) {
if (n <= 0 || n > 25)
return;
boolean[] arr =newboolean[2 * n];
catalan(arr, 0, n);
}
// Catalan序列遞歸構造方法:
// 如果當前位置前面的1的個數大於前面0的個數,當前位置可以填充1。
// 如果當前位置前面的1的個數小於n,當前位置可以填充1。
// 遞歸結束條件爲當前位置前面的1的個數等於n,則當前位置到序列結尾都填充0,構造結束。
public static void catalan(boolean[] arr,int index,int trueLeft) {
if (trueLeft == 0) {
char[] array =newchar[arr.length + 1];
char ch ='a';
for (int i = 0; i < index; i++) {
if (arr[i])
array[i] = ch++;
else
array[i] = NULLNODE;
}
for(int i=index;i<array.length;i++)
array[i] = NULLNODE;
testBinTree(array);
} else {
arr[index] = true;
catalan(arr, index + 1,trueLeft - 1);
if (index + 1 <= arr.length - 2 * trueLeft) {
arr[index] = false;
catalan(arr, index + 1,trueLeft);
}
}
}
public static void Print(String str) {
System.out.print(str);
}
public static void Println() {
System.out.println();
}
public static void Println(String str) {
Print(str);
Println();
}
}
參考鏈接:
http://blog.csdn.net/kofsky/article/details/2886453
下載地址: