请设计一个算法判断二叉树T是否为一棵完全二叉树,若是,返回1;否则返回0.
解题思路:构建二叉树;用data值为0的结点看作空结点。
1.采用层次遍历。其中要将所有结点加入队列,包括空结点。
2.判断在空结点之后,是否有非空结点,若有则返回0,无则继续判断,直至层次遍历完成。
#include<stdio.h>
#include<string>
#include<algorithm>
using namespace std;
//string qx="12400500300";//完全二叉树测试数据
//string zx="04020501030";
string qx="1230000" ;//非完全二叉树测试数据
string zx="0302010";
const int MaxSize=100;
typedef struct Tree//二叉树结构定义
{
int data;
Tree *left;
Tree *right;
} *BiTree;
typedef struct LinkNode//链式队列结点
{
BiTree data;
LinkNode *next;
}LinkNode;
typedef struct//链式队列
{
LinkNode *front,*rear;//队列的队头和队尾指针
}LinkQueue;
void InitQueue(LinkQueue &Q)//初始化
{
Q.rear=Q.front=(LinkNode*)malloc(sizeof(LinkNode));//建立头结点
Q.front->next=NULL;//初始为空
}
bool IsEmpty(LinkQueue Q)//判队空
{
if(Q.rear==Q.front) return true;//队空条件
else return false;
}
void EnQueue(LinkQueue &Q,BiTree x)//入队
{
LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));
s->data=x;//创建新结点,插入到链尾
s->next=NULL;
Q.rear->next=s;
Q.rear=s;
}
bool DeQueue(LinkQueue &Q,BiTree &x)
{
if(Q.rear==Q.front) return false;//空队
LinkNode *p=Q.front->next;
x=p->data;
Q.front->next=p->next;
if(Q.rear==p) Q.rear=Q.front;
return true;
}
BiTree build(string qx,string zx)
{
if(qx.size()==0)return NULL;
Tree *root=(Tree *)malloc(sizeof(Tree));
root->data=qx[0]-'0';
int pos=zx.find(qx[0]);
root->left=build(qx.substr(1,pos),zx.substr(0,pos));
root->right=build(qx.substr(pos+1),zx.substr(pos+1));
return root;
}
int CompleteTree(BiTree T)//函数主体
{
LinkQueue Q;
InitQueue(Q);//初始化队列
if(T==NULL)//若树为空则为完全二叉树
{
return 1;
}
BiTree p=T;//设置工作指针p
EnQueue(Q,p);//根结点入队
BiTree z=Q.front->next->data;
printf("头头是%d\n",(*z).data);
while(!IsEmpty(Q))//队列不空时,循环
{
//printf("*******");
DeQueue(Q,p);//出队
printf("chulai==%d\n",p->data);
if(p->data!=0)//若p为非空结点,则将p的左右孩子入队
{
EnQueue(Q,p->left);
EnQueue(Q,p->right);
}
else//若p为空结点,则开始向后判断是否有非空结点。若有,则不是完全二叉树,若没有则是完全二叉树。
{
while(!IsEmpty(Q))
{
DeQueue(Q,p);
if(p->data!=0)//若p结点非空,则非完全二叉树
{
return 0;
}
}
}
}
return 1;
}
void preorder(BiTree root,int level)//函数主体
{
if(root==NULL) return;//空树直接返回
printf("data:%d level:%d\n",root->data,level);//输出结点及层数
preorder(root->left,level+1);//递归遍历左子树
preorder(root->right,level+1); //递归遍历右子树
}
int main()
{
LinkQueue Q;
BiTree root=build(qx,zx);
preorder(root,0);
int i=CompleteTree(root);
printf("%d\n",i);
}