定义
首先需要先了解完全二叉树的定义
完全二叉树: 完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。
满二叉树: 一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是 ,则它就是满二叉树
所以有 满二叉树是特殊的完全二叉树
通俗来说,完全二叉树 就是k-1层节点全满,最后一层(k层)从左到右的节点当遇到空,那么后面全是空。
性质
二叉树的性质:
-
若规定根节点的层数为1,则一棵非空二叉树的 第i层上最多有
2^(i-1)
个结点. -
若规定根节点的层数为1,则深度为h的二叉树的最大结点数是
(2^h)-1
. -
对任何一棵二叉树, 如果度为0其叶结点个数为
n0
, 度为2的分支结点个数为n2
,则有n0=n2+1
. -
若规定根节点的层数为1,具有n个结点的满二叉树的深度
h=log2(n+1)
. -
对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:
a.
若i>0,i位置节点的双亲序号:(i-1)/2;i=0,i为根节点编号,无双亲节点
b.
若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子
c.
若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子
题目
判断一个树是不是完全二叉树
- 首先定义一个队列q,并将根节点指针root插入队列中。
- 进入循环,只要队列不为空,就进行以下操作:
a.
取出队列的队首元素front,并弹出队列。
b.
如果front为空,说明遇到了二叉树的空节点,此时跳出循环。
c.
如果front不为空,将front的左右子节点指针分别插入队列中。 - 循环结束后,如果队列中还存在元素,则说明二叉树不是完全二叉树,直接返回false。如果队列中已经没有元素了,说明二叉树是完全二叉树,返回true。
注意操作过程中并没有进行二叉树内节点的删改,只是把根节点front指针改动
bool IsCompleteBinaryTree(BTNode* root)
{
Queue q;
QueueInit(&q);
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
//遇到空节点跳出循环,不是空则继续插入左右子树分别插入队列中
if (front == NULL)
{
break;
}
else
{
QueuePush(&q, front->left);
QueuePush(&q, front->right);
}
}
//遇到空跳出后,有两种情况
//后面元素全是空,则是完全二叉树
//后面元素有非空,则不是完全二叉树
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
//如果存在非空,则不是完全二叉树
if (front)
{
//返回前销毁队列
QueueDestory(&q);
return false;
}
}
QueueDestory(&q);
return true;
}