对于二叉树的存储,同样分为链式存储和顺序存储。
今日的代码主要讨论的就是顺序存储,可以直接存储在数组中,按照根节点、左孩子、右孩子、左孩子的左孩子、左孩子的右孩子、右孩子的左孩子......的层序遍历的顺序进行存储,在空的位置用0来存储。
除此之外,可以设置一个二维数组,一个存储值,另外一个存储位置。即此时把数组下标为1的存储根节点,数组下标为2时存储左孩子,数组下标为4时存储左孩子的左孩子。
这是发现存储过程是对于二叉树的层序遍历,层序遍历要用到队列。把根节点入队,出队存储到数组的同时,让出队节点的左右孩子入队。再让队首节点出队,存入数组中,将其左右孩子入队。
1.队列代码:
ackage datastructure.queue;
public class CircleObjectQueue {
public static final int TOTAL_SPACE = 10;
Object[] data;
int head;
int tail;
public CircleObjectQueue() {
data = new Object[TOTAL_SPACE];
head = 0;
tail = 0;
}// Of the first constructor
/**
*********************
* Enqueue.
*
* @param paraValue
* The value of the new node.
*********************
*/
public void enqueue(Object paraValue) {
if ((tail + 1) % TOTAL_SPACE == head) {
System.out.println("Queue full.");
return;
} // Of if
data[tail % TOTAL_SPACE] = paraValue;
tail++;
}// Of enqueue
public Object dequeue() {
if (head == tail) {
//System.out.println("No element in the queue");
return null;
} // Of if
Object resultValue = data[head];
head++;
return resultValue;
}// Of dequeue
public String toString() {
String resultString = "";
if (head == tail) {
return "empty";
} // Of if
for (int i = head; i < tail; i++) {
resultString += data[i % TOTAL_SPACE] + ", ";
} // Of for i
return resultString;
}// Of toString
public static void main(String args[]) {
CircleObjectQueue tempQueue = new CircleObjectQueue();
}// Of main
}// Of CircleObjectQueue
2.存储二叉树
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);
}
if (tempTree.rightChild != null) {
tempQueue.enqueue(tempTree.rightChild);
tempIntQueue.enqueue(tempIndex * 2 + 2);
}
tempTree = (BinaryCharTree) tempQueue.dequeue();
tempIndex = tempIntQueue.dequeue();
}
}
总结:除了两种顺序存储,还有链式存储。因为顺序存储的方式导致空间利用率较低,利用链式存储会有效避免这一问题。
存储代码如下,定义节点为三部分
public class BiNode {
public String data;//data域
public BiNode leftChild;//左指针域
public BiNode rightChild;//右指针域
}
首先找到根结点,设置为链式结构的root();
根据完全二叉树的特性,对于任意一个结点i,它的左孩子和2i,右孩子为2i+1; 所以从根结点开始递归的访问它的左孩子(2i结点),直到左孩子不存在;然后再递归的访问它的右孩子(2i+1结点),直到右孩子不存在。
整个递归访问过程结束后,二叉树数组结构就转换为链式结构了。