1.相当于在21天的代码中添加了一个构造方法,也相当于22天的逆过程.
2.保留了调试语句.
3.使用一个线性表先分配所有节点的空间, 再将节点链接起来.
4,最后并没有返回, 而是把第 0 个节点的相应值拷贝给自己.
package dataStructure.tree;
import java.util.Arrays;
import dataStructure.queue.*;
/**
* @author goudiyuan
*/
public class BinaryCharTree {
// 字符中的值
char value;
// 左孩子
BinaryCharTree leftChild;
// 右孩子
BinaryCharTree rightChild;
// 构造方法
public BinaryCharTree(char paraName) {
value = paraName;
leftChild = null;
rightChild = null;
}
// 第一个构造函数
// 手动建立一个二叉树
public static BinaryCharTree manualConstructTree() {
// 第一步,构造一个只有一个节点的树。
BinaryCharTree resultTree = new BinaryCharTree('a');
// 第二步,构造所有的节点,第一个节点是根节点
// 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');
// 第三步,连接所有的节点
resultTree.leftChild = tempTreeB;
resultTree.rightChild = tempTreeC;
tempTreeB.rightChild = tempTreeD;
tempTreeC.leftChild = tempTreeE;
tempTreeD.leftChild = tempTreeF;
tempTreeD.rightChild = tempTreeG;
return resultTree;
}
/**
********************
* 第二个构造函数.参数必须正确,因为没有有效性 进行检查
*
* @see #paraDataArray 数据的数组
* @see #paraIndicesArray 索引的数组
*
*********************
*/
public BinaryCharTree(char[] paraDataArray, int[] paraIndicesArray) {
// 第一步,使用一个线性表先来存储所有的节点
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
// 第二步,连接所有的节点
for (int i = 1; i < tempNumNodes; i++) {
for (int j = 0; j < i; j++) {
System.out.println("索引 " + paraIndicesArray[j] + " vs. " + paraIndicesArray[i]);
if (paraIndicesArray[i] == paraIndicesArray[j] * 2 + 1) {
tempAllNodes[j].leftChild = tempAllNodes[i];
System.out.println("连接 " + j + " 和 " + i);
break;
} // of if
else if (paraIndicesArray[i] == paraIndicesArray[j] * 2 + 2) {
tempAllNodes[j].rightChild = tempAllNodes[i];
System.out.println("连接 " + j + " 和 " + i);
break;
} // of else if
} // of for j
} // of for i
// 第三步,根节点是第一个节点
value = tempAllNodes[0].value;
leftChild = tempAllNodes[0].leftChild;
rightChild = tempAllNodes[0].rightChild;
}// of second constructor
// 前序遍历
public void preOrderVisit() {
System.out.print("" + value + " ");
if (leftChild != null) {
leftChild.preOrderVisit();
}
if (rightChild != null) {
rightChild.preOrderVisit();
}
}
// 中序遍历
public void inOrderVisit() {
if (leftChild != null) {
leftChild.inOrderVisit();
}
System.out.print("" + value + " ");
if (rightChild != null) {
rightChild.inOrderVisit();
}
}
// 后序遍历
public void postOrderVisit() {
if (leftChild != null) {
leftChild.postOrderVisit();
}
if (rightChild != null) {
rightChild.postOrderVisit();
}
System.out.print("" + value + " ");
}
// 获取二叉树的深度。
// 返回深度。如果只有一个节点,即根节点,则为 1。
// 递归就是香
public int getDepth() {
// 是叶子
if ((leftChild == null) && (rightChild == null)) {
return 1;
}
// 左孩子的深度
int tempLeftDepth = 0;
if (leftChild != null) {
tempLeftDepth = leftChild.getDepth();
}
// 右孩子的深度
int tempRightDepth = 0;
if (rightChild != null) {
tempRightDepth = rightChild.getDepth();
}
// 深度递增1
if (tempLeftDepth >= tempRightDepth) {
return tempLeftDepth + 1;
} else {
return tempRightDepth + 1;
}
}
// 获取节点数,并返回节点总数
// 妙啊
public int getNumNodes() {
// 是叶子节点
if ((leftChild == null) && (rightChild == null)) {
return 1;
}
// 左孩子的节点
int tempLeftNodes = 0;
if (leftChild != null) {
tempLeftNodes = leftChild.getNumNodes();
}
// 右孩子的节点
int tempRightNodes = 0;
if (rightChild != null) {
tempRightNodes = rightChild.getNumNodes();
}
// 节点总数
return tempLeftNodes + tempRightNodes + 1;
}
/**
* 节点的值根据广度优先遍历。
*/
char[] valuesArray;
/**
* 完整二叉树中的索引
*/
int[] indicesArray;
/**
********************
* 将树转换为数据数组,包括 char 数组和 int 数组。完整二叉树中的索引。 他的结果储存在两个成员变量当中
*
* @see #valuesArray 这个放char
* @see #indicesArray 这个放int
*
*********************
*/
public void toDataArrays() {
// 初始化数组
int tempLength = getNumNodes();
valuesArray = new char[tempLength];
indicesArray = new int[tempLength];
int i = 0;
// 同时遍历和转换数组.
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
/**
********************
* 将树转换为数据数组,包括 char 数组和 int 数组。完整二叉树中的索引。 他的结果储存在两个成员变量当中
*
* @see #valuesArray 这个放char
* @see #indicesArray 这个放int
*********************
*/
public void toDataArraysObjectQueue() {
// 初始化.
int tempLength = getNumNodes();
valuesArray = new char[tempLength];
indicesArray = new int[tempLength];
int i = 0;
// 同时遍历和转换
CircleObjectQueue tempQueue = new CircleObjectQueue();
tempQueue.enqueue(this);
CircleObjectQueue tempIntQueue = new CircleObjectQueue();
Integer tempIndexInteger = new Integer(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(new Integer(tempIndex * 2 + 1));
} // Of if
if (tempTree.rightChild != null) {
tempQueue.enqueue(tempTree.rightChild);
tempIntQueue.enqueue(new Integer(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 static void main(String args[]) {
BinaryCharTree temptree = manualConstructTree();
System.out.println("\r\n前序遍历:");
temptree.preOrderVisit();
System.out.println("\r\n中序遍历:");
temptree.inOrderVisit();
System.out.println("\r\n后序遍历:");
temptree.postOrderVisit();
System.out.println("\r\n\r\n深度为: " + temptree.getDepth());
System.out.println("节点总数为: " + temptree.getNumNodes());
temptree.toDataArrays();
System.out.println("数据为: " + Arrays.toString(temptree.valuesArray));
System.out.println("索引为: " + Arrays.toString(temptree.indicesArray));
temptree.toDataArraysObjectQueue();
System.out.println("仅对象队列");
System.out.println("数据为: " + Arrays.toString(temptree.valuesArray));
System.out.println("索引为: " + Arrays.toString(temptree.indicesArray));
System.out.println();
char[] tempCharArray = { 'A', 'B', 'C', 'D', 'E', 'F' };
int[] tempIndicesArray = { 0, 1, 2, 4, 5, 12 };
System.out.println("数据为: " + Arrays.toString(tempCharArray));
System.out.println("索引为: " + Arrays.toString(tempIndicesArray));
System.out.println();
BinaryCharTree temptree2 = new BinaryCharTree(tempCharArray, tempIndicesArray);
System.out.println("\r\n前序遍历:");
temptree2.preOrderVisit();
System.out.println("\r\n中序遍历:");
temptree2.inOrderVisit();
System.out.println("\r\n后序遍历:");
temptree2.postOrderVisit();
}
}
运行结果
前序遍历:
a b d f g c e
中序遍历:
b f d g a e c
后序遍历:
f g d b e c a深度为: 4
节点总数为: 7
队列中已经没有元素
数据为: [a, b, c, d, e, f, g]
索引为: [0, 1, 2, 4, 5, 9, 10]
tempIndex = 0
仅对象队列
数据为: [a, b, c, d, e, f, g]
索引为: [0, 1, 2, 4, 5, 9, 10]数据为: [A, B, C, D, E, F]
索引为: [0, 1, 2, 4, 5, 12]索引 0 vs. 1
连接 0 和 1
索引 0 vs. 2
连接 0 和 2
索引 0 vs. 4
索引 1 vs. 4
连接 1 和 3
索引 0 vs. 5
索引 1 vs. 5
索引 2 vs. 5
连接 2 和 4
索引 0 vs. 12
索引 1 vs. 12
索引 2 vs. 12
索引 4 vs. 12
索引 5 vs. 12
连接 4 和 5前序遍历:
A B D C E F
中序遍历:
B D A E F C
后序遍历:
D B F E C A