1.前言
在前面几天对树的代码懵懵懂懂的时候,自己确实被小小的折磨了一下,对于不懂地方,参考了许多资料以及老师曾经发的博客,对以前概念的错误理解以及对代码的理解有了更新的认识。
2.二叉树的建立
这一天的内容,是通过输入二叉树节点的值以及编号,逆向构建二叉树,首先通过一个线性表来存储所有节点,再进行链接。
3.代码实现
/*
* ************************************ ************************************
*/
// paraDataArray 数值的数组 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. 手动构建二叉树,利用编号来寻找父母与左右孩子的关系 链接所有节点,@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
/**
*********************
* 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();
}// Of main
运行结果:
// Step 3. 根节点
value = tempAllNodes[0].value;
leftChild = tempAllNodes[0].leftChild;
rightChild = tempAllNodes[0].rightChild;
在这一段代码中,最开始还没注意到这一段有什么用,因为前面已经构建完了二叉树,所以最开始有点疑惑。后来在实验中发现,这段代码是为了遍历节点时能回到根节点开始。
4.总结
在前几天的方法中,最开始是使用给出节点,手动去挨个链接彼此节点的关系,最后实现遍历和计算深度以及计算节点数量的方法。再后来就学习了二叉树的存储,在存储的这段内容里,由于将老师的代码当成同一个包,但是不同类的代码了,这就导致我在编写时,发现有些地方出现错误,最终造成了一些误解,走入了歧途,导致那两天神志不清。在今天的这段代码中,是通过另外一种方法来实现二叉树的构建,给出节点以及编号,通过父子之间的编号关系来得出节点间的逻辑关系,这种方法的代码具有更高的复用性,第一种手动创建的方法,如果节点数量多了的话,连接起来不仅人的思维麻烦,代码简洁性也将变得非常低。第二种方法则有效解决了这种情况。总的来说,这几天通过树的代码收货颇丰,其代码大量体现了JAVA面向对象的思想,例如使用通用类型的存储,将需要的东西,通过强制类型转换,将其转成自身的类别,赋予每个对象的属性以及行为。