1. 二叉树深度遍历的栈实现 (中序)
像之前一样,建立一个通用栈,以增加代码复用性,直接强制转换类型就行。
1.1具有通用性的对象栈
- 改写栈程序, 里面存放对象.
- 该程序应该放在 datastructure.stack 包内.
- 还是依靠强制类型转换, 支持不同的数据类型.
- 增加了 isEmpty() 方法来判断是否栈空
1.1.1代码实现
package tree;
public class ObjectStack {
/**
* Circle int queue.
*
* @author Fan Min minfanphd@163.com.
*/
// 设定最大深度
public static final int MAX_DEPTH = 10;
// 实际深度
int depth;
// 数值
Object[] data;
// 建立一个空栈
public ObjectStack() {
depth = 0;
data = new Object[MAX_DEPTH];
}// Of the first constructor
// 重写toString,输出和
public String toString() {
String resultString = "";
for (int i = 0; i < depth; i++) {
resultString += data[i];
} // Of for i
return resultString;
}// Of toString
// 使用布尔类型,返回入栈是否成功
public boolean push(Object paraObject) {
if (depth == MAX_DEPTH) {
System.out.println("Stack full.");
return false;
} // Of if
data[depth] = paraObject;
depth++;
return true;
}// Of push
// 使用布尔类型,返回出栈是否成功
public Object pop() {
if (depth == 0) {
System.out.println("Nothing to pop.");
return '\0';
} // of if
Object resultObject = data[depth - 1];
depth--;
return resultObject;
}// Of pop
// 使用布尔类型,判断栈是否为空
public boolean isEmpty() {
if (depth == 0) {
return true;
} // Of if
return false;
}// Of isEmpty
// main
public static void main(String args[]) {
ObjectStack tempStack = new ObjectStack();
// 创建栈
for (char ch = 'a'; ch < 'm'; ch++) {
tempStack.push(new Character(ch));
System.out.println("The current stack is: " + tempStack);
} // Of for i
char tempChar;
for (int i = 0; i < 12; i++) {
tempChar = ((Character) tempStack.pop()).charValue();
System.out.println("Poped: " + tempChar);
System.out.println("The current stack is: " + tempStack);
} // Of for i
}// Of main
}// Of class ObjectStack
2 中序遍历
利用栈来实现二叉树深度的中序遍历
代码:在这里省去了之前重复且无用的一部分代码,仅保留了今日二叉树深度遍历
package tree;
import java.util.Arrays;
public class BinaryCharTree2 {
char value;
// 左右孩子
BinaryCharTree2 leftChild;
BinaryCharTree2 rightChild;
// 初定义字符数
public BinaryCharTree2(char paraName) {
value = paraName;
leftChild = null;
rightChild = null;
}// Of the constructor
char[] valuesArray;
// 完全二叉树的索引
int[] indicesArray;
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 nodes.
return tempLeftNodes + tempRightNodes + 1;
}// Of getNumNodes
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);
BinaryCharTree2 tempTree = (BinaryCharTree2) 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 = (BinaryCharTree2) tempQueue.dequeue();
if (tempTree == null) {
break;
} // Of if
tempIndex = ((Integer) tempIntQueue.dequeue()).intValue();
} // Of while
}// Of toDataArraysObjectQueue
/*
* ************************************ ************************************
*/
// paraDataArray 数值的数组 paraIndicesArray 编号的数组
public BinaryCharTree2(char[] paraDataArray, int[] paraIndicesArray) {
// Step 1. 使用一个顺序表来存储所有节点
int tempNumNodes = paraDataArray.length;
BinaryCharTree2[] tempAllNodes = new BinaryCharTree2[tempNumNodes];
for (int i = 0; i < tempNumNodes; i++) {
tempAllNodes[i] = new BinaryCharTree2(paraDataArray[i]);
} // Of for i
/*
* Step 2. 手动构建二叉树,利用编号来寻找父母与左右孩子的关系 链接所有节点,@tempNumNodes 数据节点长度
*/
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. 根节点
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();
BinaryCharTree2 tempNode = this;
while (!tempStack.isEmpty() || tempNode != null) {
if (tempNode != null) {
tempStack.push(tempNode);
tempNode = tempNode.leftChild;
} else {
tempNode = (BinaryCharTree2) tempStack.pop();
System.out.print("" + tempNode.value + " ");
tempNode = tempNode.rightChild;
} // Of if
} // Of while
}// Of inOrderVisit
// main
public static void main(String args[]) {
// 逆向通过编号创建二叉树,并返回链接关系,最后进行前中后序遍历
char[] tempCharArray = { 'A', 'B', 'C', 'D', 'E', 'F' };
int[] tempIndicesArray = { 0, 1, 2, 4, 5, 12 };
BinaryCharTree2 tempTree2 = new BinaryCharTree2(tempCharArray, tempIndicesArray);
System.out.println("\r\nIn-order visit with stack:");
tempTree2.inOrderVisitWithStack();
}// Of main
}// Of BinaryCharTree
运行结果:
3 总结
今天实现的这个方法,和以前直接递归进行中序遍历不一样,递归更加符合计算机方面的逻辑?(此处该怎么描述没有想好 = =。。),代码简洁性更高。今天通过栈的方式,循环往下,更像是我们人在做题时,手动计算二叉树遍历的过程。思考起来更加简单,但是代码写起来的复杂程度也大幅提升。如果要我选的话,我肯定还是第一种递归,写起来方便。。。。