持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
二叉树的深度遍历的递归实现
二叉树的遍历
前序遍历:根-左子树-右子树;
中序遍历:左子树-根-右子树;
后序遍历:左子树-右子树-根;
在实现二叉树的遍历时,按这种顺序实现递归,递归把把复杂的问题转化为与原来问题相似的但规模较小的问题去解决。而在二叉树的遍历中就是对递归的一个很好应用。
二叉树的存储
思路
(结合下图来理解将二叉树存入数组中)对应完全二叉树来计算结点存储索引位置,则当双亲结点为i,则左子树存储的索引为2*i+1; 右子树为2*i+2;而文章中的第二个方法则是把存储值和存储索引分开,这样当树较大时可以节省空间。
层次遍历
我结合在二叉树的存储中会用到层次遍历,所以自己加了一个方法:用队列来实现层次遍历并已成功通过测试(队列先进先出特点)在CircleQueue中增加了一个isEmpty方法。
/**
* level visit.
*/
public void levelVisit(BinaryCharTree tree) {
CircleQueue tempQueue = new CircleQueue();
tempQueue.enqueue(tree);
while (tempQueue.isEmpty()) {
BinaryCharTree tempTree = (BinaryCharTree)tempQueue.dequeue();
char value = tempTree.value;
System.out.println("" + value + " ");
if (tempTree.leftChild != null) {
tempQueue.enqueue(tempTree.leftChild);
}
if (tempTree.rightChild != null) {
tempQueue.enqueue(tempTree.rightChild);
}
}
}
CircleQueue
public boolean isEmpty() {
if (head == tail) {
return false;
}
return true;
}
二叉存储
结合上面的内容,再去看二叉存储就会很好理解。把每个节点依次遍历(可参考层次遍历),遍历存放到第一个数组,同时参考完全二叉树的特性以及存储将每个遍历到的节点存储到另一个数组中,这样就实现了二叉树的存储。
使用具有通用性的队列
思路梳理
文章代码是用的一个数组存结点值,一个数组存结点的索引位置。
顺:根据二叉树关系存放结点关系在数组中。参考day22思路
逆:根据数组来还原二叉树的关系。如[a, b, c, d, e, f, g];[0, 1, 2, 4, 5, 9, 10]
对于第一个结点a,不用考虑肯定是根结点;对于第i个结点,要和那个结点有关系就要往前找(我们用的层次遍历,所以往前找,遍历i之前的结点为记为j),找符合条件的即要满足关系:i = j2 +1 或 i=j2+2
举例:如找c结点与那个结点有联系,则需要去遍历a,和 b两个结点其中是否有满足上面公式的,发现a满足,则表面a是c的双亲结点。
有了这个思路再去看代码会发现很容易理解。
总结
今天主要围绕二叉树的存储以及建立,二叉树的遍历展开,在学习二叉树的过程中,我认为画图去模拟操作再结合代码去学习会更容易理解。