#include<stdio.h>
#include<stdlib.h>
typedef struct bitree
{
char data;
struct bitree *lchild,*rchild;
}bitree;
int main()
{
bitree* createbitree(int i,int *j,bitree *t,char *ch);
void lordertraverse(bitree *t);
int i,*j,a;
char *ch;
bitree *t;
t=NULL;
a=1;
j=&a;
ch=(char *)malloc(2*sizeof(char));
i=1;
fflush(stdin);
printf("我的输入方式是先序输入,空节点位置输入0,#代表结束输入\n");
printf("注意输入一个字母按一下回车\n");
printf("请输入二叉树:\n");
scanf("%c",&ch[i]);
while(ch[i]!='#')
{
i++;
ch=(char *)realloc(ch,(i+1)*sizeof(char));
fflush(stdin);
scanf("%c",&ch[i]);
}
i--;
t=createbitree(i,j,t,ch);
lordertraverse(t);
}
bitree* createbitree(int i,int *j,bitree *t,char *ch)//i是总结点数j是当前结点数
{
if(*j>i||ch[*j]=='0'||ch[*j]=='#')
t=NULL;
else
{
t=(bitree *)malloc(sizeof(bitree));//这里就是关键请注意,当运行完之后t就不是原先的t了原本的t是特德根节点的左或者右的指针,当运行完这一行之后,T就另外开辟了一个属于自己的空间所以就脱钩了,
t->data=ch[*j];
(*j)++;
t->lchild=createbitree(i,j,t->lchild,ch);//跟书上有一点不大一样之所以要返回一个数值是因为,在这个函数运行期间有t=(bitree *)malloc(sizeof(bitree));一个式子运行完函数之后前后的t所代表的位置是不一样的。
(*j)++;
t->rchild=createbitree(i,j,t->rchild,ch);
}
return(t);
}
void visit(bitree *t)
{
printf("%c",t->data);
}
void lordertraverse(bitree *t)//层序遍历二叉树
{
bitree* *a;
int i,j,k,l,m,o,p,q;
if(t)
{
m=50;
a=(bitree **)malloc(m*sizeof(bitree *));//a是存放二叉树结点的数组
a[1]=t;//初始化a[1]存放根节点
o=0;k=1,j=1,i=1,l=1;p=q=1;//k代表此时a中最后一个结点的坐标,j是上一次的节点数,i是判断本层结点是否全为空,l表示中介,o是记录二叉树的层,p是记录次层的结点数,q是记录最后一层的结点数
while(i)//当本层结点都是空结点时中止循环
{
p=q;
q=i;
o++;//记录行
i=0;//默认状态在本层中所有的节点都是空结点
while(j<=k)//j是上一层的节点数
{
if(a[j]->lchild)
{l++,a[l]=a[j]->lchild,i++;}//如果有结点不为空i=1
if(l+1==m)//空间不足时开辟空间
{
a=(bitree **)realloc(a,(m+10)*sizeof(bitree *));
m+=10;
}
if(a[j]->rchild)
{l++;a[l]=a[j]->rchild,i++;}
if(l+1==m)
{
a=(bitree **)realloc(a,(m+10)*sizeof(bitree *));
m+=10;
}
j++;
}
k=l;
}
l=1;
for(i=1;i<=o-1;i++)
l*=2;
if(p)
{
for(i=k-q+1;i<=k;i++)
if(i%2==0)
{
if(a[i]!=a[i/2]->lchild)
break;
}
else
{
if(a[i]!=a[(i-1)/2]->rchild)
break;
}
if(i>k)
printf("是完全二叉树");
else
printf("不是完全二叉树");
}
}
}
![](https://img2024.cnblogs.com/blog/35695/202408/35695-20240813180353098-2140851696.jpg)