对于二叉树的内容,还剩下一点没有进行补充,所以在这节中对剩下的内容进行补充。
1. 二叉树的销毁
如果想要使用前序遍历的方式来对二叉树进行销毁,那么首先销毁的便是根节点,这就会导致子树的节点找不到,中序遍历也如此,所以使用后序遍历是最合适的。
代码实现如下:
cpp
//二叉树的销毁(采用后序遍历的方法进行二叉树销毁)
void TreeDestroy(BTNode* root)
{
if (root == NULL)
return;
TreeDestroy(root->Left);
TreeDestroy(root->Right);
free(root);
}
2. 层序遍历
前面学习了前序遍历,中序遍历和后序遍历,这三种遍历方式都属于深度遍历(DFS);层序遍历是按照从上到下的层次,从左向右输出每层的数据,属于广度遍历(BFS)。
实现思路:构建一个队列,利用队列先进先出的特点,每当一个拥有子树的根节点出队列时,就要将他的子树节点入队列,以此循坏,直到队列中的元素都出节点。
代码实现:
cpp
//层序遍历(采用队列进行实现)
void TreeLevelOrder(BTNode* root)
{
Queue q;
QueueInit(&q);
if (root)
QueuePush(&q, root);//二叉树不为空就将根节点入队列
while (!QueueEmpty(&q))//出一个根节点,就将其子树入队列
{
BTNode* Front = QueueFront(&q);//获取队列头节点(第一个根节点)
QueuePop(&q);
printf("&d ", Front->data);
if (Front->Left)
QueuePush(&q, Front->Left);//刚刚出队列的根节点如果有子树,就将子树节点入队列(左子树)
if(root->Right)
QueuePush(&q, Front->Left);//同上(右子树)
}
QueueDestroy(&q);
}
3. 判断二叉树是否为完全二叉树
采用类似层序遍历的队列处理方式,但需针对完全二叉树的定义进行特殊判断。
实现思路:
初始化队列并将根节点入队。开始循环处理队列,直到队列为空。
每次从队列头部取出一个节点进行检查。若该节点非空,将其左右子节点(无论是否为空)依次入队。若该节点为空,此时需要检查队列中剩余节点是否全为空。
若遇到空节点后队列中仍存在非空节点,说明二叉树存在非连续的空节点位置,违反完全二叉树的定义。若队列剩余节点全为空,则符合完全二叉树的定义。
代码实现如下:
cpp
//判断二叉树是否为完全二叉树
bool TreeComplete(BTNode* root)
{
Queue q;
QueueInit(&q);
if (root);
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
//遇到第一个空节点就开始判断,如果剩余队列中含有非空节点则不是完全二叉树,反之则是
if (front == NULL)
{
break;//跳出循环,对剩余队列进行判断
}
if (front->Left)
QueuePush(&q, front->Left);
if (front->Right)
QueuePush(&q, front->Right);
}
while (!QueueEmpty)//判断剩余队列情况
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front)//front不为NULL,说明有非空节点出队列了,就不是完全二叉树
{
QueueDestroy(&q);
return false;
}
}
QueueDestroy(&q);
return true;
}
接下来用图解法来解释一下这个方法为什么可以判断出二叉树是否为完全二叉树:

4. 二叉树性质补充
- 若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1)个结点.
- 若规定根结点的层数为1,则深度为h的二叉树的最大结点数是 2^h - 1.
- 对任何一棵二叉树, 如果度为0其叶结点个数为n0, 度为2的分支结点个数为n2,则有n0=n2 +1.(这点性质需要牢记)
- 若规定根结点的层数为1,具有n个结点的满二叉树的深度,h=log2(n+1). (ps:log2(n+1) 是log以2 为底,n+1为对数)
- 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有结点从0开始编号,则对 于序号为i的结点有:
- 若i>0,i位置结点的双亲序号:(i-1)/2;i=0,i为根结点编号,无双亲结点.
- 若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子.
- 若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子.
为了体会到性质3的知识点的运用,展示一道例题来加深印象:

解答:
