Day 25
1. Background
今天是学习java的第25天,今天的学习是接着昨天,完成二叉树的先序和后序遍历。
2. Description
先复制一下昨天的理解:
我的理解是先建立一个栈,然后创建一个tempNode
,用这个来存要遍历的节点。
然后利用栈先进先出的特性,只要tempNode
不为空,就把这个节点压入栈中,然后向它的左孩子遍历。
而当tempNode
遍历到空之后,则说明已经到了树的最左边。
PS:此时说的最左边是一个相对的概念,应该说是压到栈中的节点的最左端
此时就可以开始出栈了,由于栈后进先出的特性,最左边的那个节点就被输出。
2.1 Pre-order
这个我觉得还是很简单的,直接根据昨天的中序改就行。因为昨天的中序是先找到根节点,然后从根节点开始往左孩子遍历,当tempNode
走到null
时再遍历右孩子。只不过打印是放在中间也就是println
放在遍历右孩子之前。
根据这个,我们今天的先序遍历,直接把打印提到最初遍历根的地方即可。
2.2 Post-Order
这个的理论同上,不过后序遍历有点麻烦,不能直接在像先序一样循环里面的右孩子之后写println
,
需要建立一个outputStack
把输出的存着,然后再循环结束之后再输出。
3. Code
package datastructure;
import java.util.Arrays;
public class BinaryCharTree {
/**
* The value of node.
*/
char value;
/**
* 二叉树的左孩子。
*/
BinaryCharTree leftChild;
/**
* 二叉树的右孩子。
*/
BinaryCharTree rightChild;
/**
**************
* The first constructor.
*
* @param paraValue The given value.
**************
*/
public BinaryCharTree(char paraValue) {
value = paraValue;
leftChild = null;
rightChild = null;
} // Of the first construe
/**
**************
* Reload BinaryCharTree.
*
* @param paraDataArray
* @param paraIndicesArray
**************
*/
public BinaryCharTree(char[] paraDataArray, int[] paraIndicesArray) {
// Step 1. 把二叉树存到顺序表中。
int tempNumNodes = paraDataArray.length;
BinaryCharTree[] tempAllNodes = new BinaryCharTree[tempNumNodes];
for (int i = 0; i < tempNumNodes; i++) {
tempAllNodes[i] = new BinaryCharTree(paraDataArray[i]);
} // Of for i
// Step 2. Link nodes.
for (int i = 1; i < tempNumNodes; i++) {
for (int j = 0; j < i; j++) {
System.out.println("indices " + paraIndicesArray[j] + " vs. " + paraIndicesArray[i]);
if (paraIndicesArray[i] == paraIndicesArray[j] * 2 + 1) { // 节点序号从0开始,故此处为左孩子
tempAllNodes[j].leftChild = tempAllNodes[i];
System.out.println("Linking " + j + " with " + i);
break;
} else if (paraIndicesArray[i] == paraIndicesArray[j] * 2 + 2) {
tempAllNodes[j].rightChild = tempAllNodes[i];
System.out.println("Linking " + j + " with " + i);
break;
} // Of if
} // Of for j
} // Of for i
// 返回二叉树的根节点
value = tempAllNodes[0].value;
leftChild = tempAllNodes[0].leftChild;
rightChild = tempAllNodes[0].rightChild;
} // Of the the second constructor
public static BinaryCharTree manualConstructTree() {
// step 1. Creat root.
BinaryCharTree resultTree = new BinaryCharTree('a');
// step 2. creat children and linked them.
BinaryCharTree tempTreeB = new BinaryCharTree('b');
BinaryCharTree tempTreeC = new BinaryCharTree('c');
BinaryCharTree tempTreeD = new BinaryCharTree('d');
BinaryCharTree tempTreeE = new BinaryCharTree('e');
BinaryCharTree tempTreeF = new BinaryCharTree('f');
BinaryCharTree tempTreeG = new BinaryCharTree('g');
// Link strat
resultTree.leftChild = tempTreeB;
resultTree.rightChild = tempTreeC;
tempTreeB.rightChild = tempTreeD;
tempTreeC.leftChild = tempTreeE;
tempTreeD.leftChild = tempTreeF;
tempTreeD.rightChild = tempTreeG;
return resultTree;
} // Of manualConstructTree
/**
**************
* 先根、中根、后根遍历树。
**************
*/
public void preOrderVisit() {
System.out.print(value + " ");
if (leftChild != null) {
leftChild.preOrderVisit();
} // Of if
if (rightChild != null) {
rightChild.preOrderVisit();
} // Of if
} // Of preOrderVisit
public void inOrderVisit() {
if (leftChild != null) {
leftChild.inOrderVisit();
} // Of if
System.out.print(value + " ");
if (rightChild != null) {
rightChild.inOrderVisit();
} // Of if
}
public void postOrderVisit() {
if (leftChild != null) {
leftChild.postOrderVisit();
} // Of if
if (rightChild != null) {
rightChild.postOrderVisit();
} // Of if
System.out.print(value + " ");
}
public int getDepth() {
if ((leftChild == null) && (rightChild == null)) {
return 1;
} // Of if
// check left
int tempLeftDepth = 0;
if (leftChild != null) {
tempLeftDepth = leftChild.getDepth();
} // Of if
// Check right
int tempRightDepth = 0;
if (rightChild != null) {
tempRightDepth = rightChild.getDepth();
} // Of if
if (tempLeftDepth >= tempRightDepth) {
return tempLeftDepth + 1;
} else {
return tempRightDepth + 1;
} // Of if
} // Of getDepth
// 遍历时存储节点中的值。
char[] valueArray;
// 二叉树的索引。
int[] indicesArray;
public void toDataArrays() {
int tempLength = getNumNodes();
valueArray = new char[tempLength];
indicesArray = new int[tempLength];
int i = 0;
CircleObjectQueue tempQueue = new CircleObjectQueue();
tempQueue.enQueue(this);
CircleObjectQueue tempIntQueue = new CircleObjectQueue();
tempIntQueue.enQueue(0);
BinaryCharTree tempTree = (BinaryCharTree) tempQueue.deQueue();
int tempIndex = (int) tempIntQueue.deQueue();
while (tempTree != null) {
valueArray[i] = tempTree.value;
indicesArray[i] = tempIndex;
i++;
if (tempTree.leftChild != null) {
tempQueue.enQueue(tempTree.leftChild);
tempIntQueue.enQueue(tempIndex * 2 + 1);
} // Of if
if (tempTree.rightChild != null) {
tempQueue.enQueue(tempTree.rightChild);
tempIntQueue.enQueue(tempIndex * 2 + 2);
} // Of if
tempTree = (BinaryCharTree) tempQueue.deQueue();
if (tempTree != null)
tempIndex = (int) tempIntQueue.deQueue();
} // Of while
}
public int getNumNodes() {
if ((leftChild == null) && (rightChild == null)) {
return 1;
} // Of if
int tempLeftNodes = 0;
if (leftChild != null) {
tempLeftNodes = leftChild.getNumNodes();
} // Of if
int tempRightNodes = 0;
if (rightChild != null) {
tempRightNodes = rightChild.getNumNodes();
} // Of if
return tempLeftNodes + tempRightNodes + 1;
}// Of getNumNodes
public void toDataArraysObjectQueue() {
int tempLength = getNumNodes();
valueArray = new char[tempLength];
indicesArray = new int[tempLength];
int i = 0;
// 将object对象转换为想要的数据类型。
CircleObjectQueue tempQueue = new CircleObjectQueue();
tempQueue.enQueue(this);
CircleObjectQueue tempIntQueue = new CircleObjectQueue();
Integer tempIndexInteger = Integer.valueOf(0);
tempIntQueue.enQueue(tempIndexInteger);
BinaryCharTree tempTree = (BinaryCharTree) tempQueue.deQueue();
int tempIndex = ((Integer) tempIntQueue.deQueue()).intValue();
System.out.println("tempIndex = " + tempIndex);
while (tempTree != null) {
valueArray[i] = tempTree.value;
indicesArray[i] = tempIndex;
i++;
if (tempTree.leftChild != null) {
tempQueue.enQueue(tempTree.leftChild);
tempIntQueue.enQueue(Integer.valueOf(tempIndex * 2 + 1));
} // Of if
if (tempTree.rightChild != null) {
tempQueue.enQueue(tempTree.rightChild);
tempIntQueue.enQueue(Integer.valueOf(tempIndex * 2 + 2));
} // Of if
tempTree = (BinaryCharTree) tempQueue.deQueue();
if (tempTree == null) {
break;
}//Of if
tempIndex = ((Integer) tempIntQueue.deQueue()).intValue();
} // Of while
}// Of toDataArraysObjectQueue
public void inOrderVisitWithStack() {
ObjectStack tempStack = new ObjectStack();
BinaryCharTree tempNode = this;
while (!tempStack.isEmpty() || tempNode != null) {
if (tempNode != null) {
tempStack.Push(tempNode);
tempNode = tempNode.leftChild;
} else {
tempNode = (BinaryCharTree) tempStack.Pop();
System.out.print("" + tempNode.value + " ");
tempNode = tempNode.rightChild;
} // Of if
} // Of while
}// Of inOrderVisit
// 先根遍历
public void preOrderVisitWithStack() {
ObjectStack tempStack = new ObjectStack();
BinaryCharTree tempNode = this;
while (!tempStack.isEmpty() || tempNode != null) {
if (tempNode != null) {
System.out.print("" + tempNode.value + " ");
tempStack.Push(tempNode);
tempNode = tempNode.leftChild;
} else {
tempNode = (BinaryCharTree) tempStack.Pop();
tempNode = tempNode.rightChild;
} // Of if
} // Of while
}// Of preOrderVisitWithStack
// 后根遍历
public void postOrderVisitWithStack() {
ObjectStack tempStack = new ObjectStack();
BinaryCharTree tempNode = this;
ObjectStack tempOutputStack = new ObjectStack();
while (!tempStack.isEmpty() || tempNode != null) {
if (tempNode != null) {
//Store for output.
tempOutputStack.Push(new Character(tempNode.value));
tempStack.Push(tempNode);
tempNode = tempNode.rightChild;
} else {
tempNode = (BinaryCharTree) tempStack.Pop();
tempNode = tempNode.leftChild;
} // Of if
} // Of while
//Now reverse output.
while (!tempOutputStack.isEmpty()) {
System.out.print("" + tempOutputStack.Pop() + " ");
}//Of while
}// Of postOrderVisitWithStack
/**
*********************
* The entrance of the program.
*
* @param args Not used now.
*********************
*/
public static void main(String args[]) {
BinaryCharTree tempTree = manualConstructTree();
System.out.println("\r\nPreorder visit:");
tempTree.preOrderVisit();
System.out.println("\r\nIn-order visit:");
tempTree.inOrderVisit();
System.out.println("\r\nPost-order visit:");
tempTree.postOrderVisit();
System.out.println("\r\n\r\nThe depth is: " + tempTree.getDepth());
System.out.println("The number of nodes is: " + tempTree.getNumNodes());
tempTree.toDataArrays();
System.out.println("The values are: " + Arrays.toString(tempTree.valueArray));
System.out.println("The indices are: " + Arrays.toString(tempTree.indicesArray));
tempTree.toDataArraysObjectQueue();
System.out.println("Only object queue.");
System.out.println("The values are: " + Arrays.toString(tempTree.valueArray));
System.out.println("The indices are: " + Arrays.toString(tempTree.indicesArray));
char[] tempCharArray = {'A', 'B', 'C', 'D', 'E', 'F'};
int[] tempIndicesArray = {0, 1, 2, 4, 5, 12};
BinaryCharTree tempTree2 = new BinaryCharTree(tempCharArray, tempIndicesArray);
System.out.println("\r\nPreorder visit:");
tempTree2.preOrderVisit();
System.out.println("\r\nIn-order visit:");
tempTree2.inOrderVisit();
System.out.println("\r\nPost-order visit:");
tempTree2.postOrderVisit();
System.out.println("\r\nIn-order visit with stack:");
tempTree2.inOrderVisitWithStack();
System.out.println("\r\nPre-order visit with stack:");
tempTree2.preOrderVisitWithStack();
System.out.println("\r\nPost-order visit with stack:");
tempTree2.postOrderVisitWithStack();
}// Of main
}
运行结果: