1. 二叉树基于栈的前后序遍历
1.1 前序
前序与中序基本相同改变输出的位置即可。
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();
//中序
//System.out.print("" + tempNode.value + " ");
tempNode = tempNode.rightChild;
} // Of if
} // Of while
}// Of preOrderVisitWithStack
1.2 后序
后序是左右根,这里选择的是利用在前序的基础上做改变成根右左,然后再进行逆序。
比起前序,代码中需多加一个栈来逆序,改变左右子树的遍历顺序,把输出操作改为入逆序栈操作,最后再加一个逆序栈的输出操作。
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
2. 总代码
package datastructure.tree;
import java.util.Arrays;
import datastructure.queue.*;
import datastructure.stack.*;
/**
* Binary tree with char type elements.
*
* @author Yunhua Hu yunhuahu0528@163.com.
*/
public class BinaryCharTree {
/**
* The value in char.
*/
char value;
/**
* The left child.
*/
BinaryCharTree leftChild;
/**
* The right child.
*
*/
BinaryCharTree rightChild;
/**
*********************
* The first constructor
*
* @param paraName
* The value.
*********************
*/
public BinaryCharTree(char paraName) {
value = paraName;
leftChild = null;
rightChild = null;
}// Of the constructor
/**
*********************
* Manually construct a tree. Only for testing.
*********************
*/
public static BinaryCharTree manualConstructTree() {
// step 1. Construct a tree with only one node.
BinaryCharTree resultTree = new BinaryCharTree('a');
// Step 2. construct all nodes. The first node is the root.
// BinaryCharTreeNode tempTreeA = resultTree.root;
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');
// step 3. Link al nodes.
resultTree.leftChild = tempTreeB;
resultTree.rightChild = tempTreeC;
tempTreeB.rightChild = tempTreeD;
tempTreeC.leftChild = tempTreeE;
tempTreeD.leftChild = tempTreeF;
tempTreeD.rightChild = tempTreeG;
return resultTree;
}// Of manualConstructTree
/**
*********************
* Pre-order visit.
*********************
*/
public void preOrderVisit() {
System.out.print("" + value + " ");
if (leftChild != null) {
leftChild.preOrderVisit();
} // Of if
if (rightChild != null) {
rightChild.preOrderVisit();
} // Of if
}// Of preOrderVisit
/**
*********************
* In-Order visit.
*********************
*/
public void inOrderVisit() {
if (leftChild != null) {
leftChild.inOrderVisit();
} // Of if
System.out.print("" + value + " ");
if (rightChild != null) {
rightChild.inOrderVisit();
} // Of if
}// Of inOrderVisit
/**
*********************
* Post-Order visit.
*********************
*/
public void postOrderVisit() {
if (leftChild != null) {
leftChild.postOrderVisit();
} // Of if
if (rightChild != null) {
rightChild.postOrderVisit();
} // Of if
System.out.print("" + value + " ");
}// Of postOrderVisit
/**
*********************
* Get the depth of the binary tree.
*
* @return The depth. It is 1 if there is only node, i.e., the root.
*********************
*/
public int getDepth() {
// It is a leaf.
if ((leftChild == null) && (rightChild == null)) {
return 1;
} // Of if
int tempLeftDepth = 0;
if (leftChild != null) {
tempLeftDepth = leftChild.getDepth();
} // Of if
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
/**
*********************
* Get the number of nodes.
*
* @return The number of nodes.
*********************
*/
public int getNumNodes() {
// It is a leaf.
if ((leftChild == null) && (rightChild == null)) {
return 1;
} // Of if
// The number of nodes of the left child.
int tempLeftNodes = 0;
if (leftChild != null) {
tempLeftNodes = leftChild.getNumNodes();
} // Of if
// The number of nodes of the right child.
int tempRightNodes = 0;
if (rightChild != null) {
tempRightNodes = rightChild.getNumNodes();
} // Of if
// The total number of the nodes.
return tempLeftNodes + tempRightNodes + 1;
} // Of getNumNodes
/**
* The values of nodes according to breadth first traversal.
*/
char[] valuesArray;
/**
* The indices in the complete binary tree.
*/
int[] indicesArray;
/**
********************
* Convert the tree to data arrays, including a char array and an int array. The
* results are stored in two member variables.
*
* @see #valuesArray
* @see #indicesArray
*********************
*/
public void toDataArrays() {
// Initialize arrays.
int tempLength = getNumNodes();
valuesArray = new char[tempLength];
indicesArray = new int[tempLength];
int i = 0;
// Traverse and convert at the same time.
CircleObjectQueue tempQueue = new CircleObjectQueue();
tempQueue.enqueue(this);
CircleIntQueue tempIntQueue = new CircleIntQueue();
tempIntQueue.enqueue(0);
BinaryCharTree tempTree = (BinaryCharTree) tempQueue.dequeue();
int tempIndex = tempIntQueue.dequeue();
while (tempTree != null) {
valuesArray[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();
tempIndex = tempIntQueue.dequeue();
} // Of while
}// Of toDataArrays
/**
********************
* Convert the tree to data arrays, including a char array and an int array. The
* results are stored in two member variables.
*
* @see #valuesArray
* @see #indicesArray
*********************
*/
public void toDataArraysObjectQueue() {
// Initialize arrays.
int tempLength = getNumNodes();
valuesArray = new char[tempLength];
indicesArray = new int[tempLength];
int i = 0;
// Traverse and convert at the same time.
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) {
valuesArray[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
/**
*********************
* The second constructor. The parameters must be correct since no validity
* check is undertaken.
*
* @param paraDataArray
* The array for data.
* @param paraIndicesArray
* The array for indices.
*********************
*/
public BinaryCharTree(char[] paraDataArray, int[] paraIndicesArray) {
// Step 1. Use a sequential list to store all nodes.
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 these 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) {
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
// Step 3. The root is the first node.
value = tempAllNodes[0].value;
leftChild = tempAllNodes[0].leftChild;
rightChild = tempAllNodes[0].rightChild;
}// Of the the second constructor
/**
*********************
* In-order visit with stack.
*********************
*/
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
/**
*********************
* Pre-order visit with stack.
*********************
*/
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
/**
*********************
* Post-order visit with stack.
*********************
*/
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.valuesArray));
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.valuesArray));
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
}// Of BinaryCharTree
输出:
小感慨:从基础的字符整型栈队列,到通用性的对象栈队列,从二叉树的基础节点建立链接,到各种遍历方法,代码看得再多,把思路写下来,自己去写都还是可能会出现诸多小问题,真的还是和day01说的一样代码这东西就得多敲。