目录:
- 二叉树深度
- 二叉树前序遍历
- 递归实现
- 二种非递归实现
- 二叉树中序遍历:
- 递归实现
- 非递归实现
- 二叉树后序遍历:
- 递归实现
- 非递归实现
- 二叉树层次遍历
- 二叉树层次创建,创建方法遵循卡特兰数
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.youkuaiyun.com/kofsky/article/details/2886453
下载地址: