简介
完全二叉树的特点:
- 前h-2层的度都是2
- 最后一层的结点左对齐
- 不存在只有右孩子没有左孩子的结点
符号说明:
- 下文用A(B,C),代表这种树:根结点为A,A的左孩子为B,A的右孩子为C
- A(,) 代表只有根结点A,没有左右孩子
- A(B,) 代表有根结点A和其左孩子B,没有右孩子
思路
我们采取层序遍历的方式遍历结点,我们遍历结点的时候会遇到下面几种情况
- A(B,C): 该结点左右孩子都存在,是正常情况
- A(B,): 只存在左孩子,是异常情况,只能在最后两层出现
- A(,C): 只存在右孩子,是错误情况,不可能出现,直接返回 0
- A(,): 没有孩子,是异常情况,只能在最后两层出现
我们设立一个标志位flag,初值为0,用来表示异常情况的发生,当发生异常情况以后,进行++flag。在异常情况发生后,层序遍历后继结点时,后继结点都必须是没有左右孩子,否则就不是完全二叉树。
代码
#define M 100
typedef char ElemType;
typedef struct node
{
ElemType data;
struct node* lchild, * rchild;
}BTNode, * BTree;
// 完全二叉树的判定
// 采用层序遍历
int P208_8(BTree T)
{
BTree queue[M], cur;
int front = -1, rear = -1,flag=0;
queue[++rear] = T;
while (front < rear) {
cur = queue[++front];
// 判断当前是否处于异常,如果处于异常,则左右孩子为空
if (flag > 0 && cur->lchild != NULL && cur->rchild != NULL) {
return 0;
}
// 判断是否是异常情况
if (cur->lchild != NULL) {
if (cur->rchild == NULL) {
// 左非空,右空,进入异常状况
++flag;
}
}
else if (cur->rchild != NULL) {
// 左空,右非空,有问题
return 0;
}
else {
// 左右都空,进入异常状况
++flag;
}
// 左右孩子入队
if (cur->lchild != NULL) {
queue[++rear] = cur->lchild;
}
if (cur->rchild != NULL) {
queue[++rear] = cur->rchild;
}
}
return 1;
}