/*先要对二叉树进行层次遍历,在遍历过程中对每一个结点进行检查:
(1)如果当前结点没有右子树,则剩下的全部结点必须既没有左子树,又没有右子树;
(2)如果当前结点有右子树,则它必须也有左子树.
如果同时满足(1)(2),则是完全二叉树;否则不是.
对二叉树进行层次遍历需要使用队列结构.
*/
#include <stdio.h>
#include <malloc.h>
#define true 1
#define false 0
typedef int bool;
typedef char datatype;
typedef struct _node
{
datatype data;
struct _node *pleft;
struct _node *pright;
} node;
/*队列*/
typedef struct
{
bool bisempty;
int nfront;
int nrear;
int nsize;
node **pdata;
} queue;
/*队列初始化。nsize = 数组大小*/
void initqueue(queue *pque, int nsize)
{
pque->pdata = (node **)malloc(sizeof(node *) * nsize);
pque->nsize = nsize;
pque->nfront = pque->nrear = 0;
pque->bisempty = true;
}
/*入队列*/
bool inqueue(queue *pque, node *data)
{
if (pque->bisempty || pque->nrear != pque->nfront) /*判断队列是否满*/
{
pque->bisempty = false;
pque->pdata[pque->nrear] = data;
pque->nrear++;
if (pque->nrear == pque->nsize)
pque->nrear = 0;
return true;
}
else
return false;
}
/*出队列。pdatabfr为容纳数据的变量的指针*/
bool outqueue(queue *pque, node **pdatabfr)
{
if (pque->bisempty)
return false;
else
{
*pdatabfr = pque->pdata[pque->nfront];
pque->nfront++;
if (pque->nfront == pque->nsize)
pque->nfront = 0;
if (pque->nfront == pque->nrear)
pque->bisempty = true;
return true;
}
}
/*二叉树的层次遍历并判断是否为完全二叉树*/
bool leveltraverse(node *proot)
{
bool bresult = true;
bool bcomfine = false;
node *pcurnode;
queue que;
if (proot == null)
return true;
initqueue(&que,1024); /*这里不考虑队列溢出,在应用中应根据实际情况使用合适
的队列*/
inqueue(&que,proot);
while (outqueue(&que,&pcurnode))
{
if (!pcurnode->pleft && pcurnode->pright)
{
bresult = false;
break;
}
if (bcomfine && (pcurnode->pleft || pcurnode->pright))
{
bresult = false;
break;
}
if (pcurnode->pleft)
inqueue(&que,pcurnode->pleft);
if (pcurnode->pright)
inqueue(&que,pcurnode->pright);
else
bcomfine = true;
}
return bresult;
}
/*简单的测试环境*/
/* 从键盘缓冲区中读取一个不为空格且不为回车的字符 */
char getnextchar(void)
{
char ch;
do
{
ch = getchar();
} while (ch == || ch == /n);
return ch;
}
/*利用前序遍历序列建立二叉树。扩充结点用‘*’代表。前序序列从键盘输入*/
void createtree(node *root)
{
root->pleft = root->pright = null;
if (root->data != *) /* 如果不为扩充结点, 要建立左结点和右结点 */
{
root->pleft = (node *)malloc(sizeof(node));
root->pleft->data = getnextchar();
createtree(root->pleft);
root->pright = (node *)malloc(sizeof(node));
root->pright->data = getnextchar();
createtree(root->pright);
}
}
/*除去*结点*/
void trimtree(node *proot)
{
if (proot->pleft)
if (proot->pleft->data == *)
{
free(proot->pleft);
proot->pleft = null;
}
else
trimtree(proot->pleft);
if (proot->pright)
if (proot->pright->data == *)
{
free(proot->pright);
proot->pright = null;
}
else
trimtree(proot->pright);
}
void main()
{
node root;
root.data = getnextchar();
createtree(&root);
trimtree(&root);
printf("%d/n",leveltraverse(&root));
}
(1)如果当前结点没有右子树,则剩下的全部结点必须既没有左子树,又没有右子树;
(2)如果当前结点有右子树,则它必须也有左子树.
如果同时满足(1)(2),则是完全二叉树;否则不是.
对二叉树进行层次遍历需要使用队列结构.
*/
#include <stdio.h>
#include <malloc.h>
#define true 1
#define false 0
typedef int bool;
typedef char datatype;
typedef struct _node
{
datatype data;
struct _node *pleft;
struct _node *pright;
} node;
/*队列*/
typedef struct
{
bool bisempty;
int nfront;
int nrear;
int nsize;
node **pdata;
} queue;
/*队列初始化。nsize = 数组大小*/
void initqueue(queue *pque, int nsize)
{
pque->pdata = (node **)malloc(sizeof(node *) * nsize);
pque->nsize = nsize;
pque->nfront = pque->nrear = 0;
pque->bisempty = true;
}
/*入队列*/
bool inqueue(queue *pque, node *data)
{
if (pque->bisempty || pque->nrear != pque->nfront) /*判断队列是否满*/
{
pque->bisempty = false;
pque->pdata[pque->nrear] = data;
pque->nrear++;
if (pque->nrear == pque->nsize)
pque->nrear = 0;
return true;
}
else
return false;
}
/*出队列。pdatabfr为容纳数据的变量的指针*/
bool outqueue(queue *pque, node **pdatabfr)
{
if (pque->bisempty)
return false;
else
{
*pdatabfr = pque->pdata[pque->nfront];
pque->nfront++;
if (pque->nfront == pque->nsize)
pque->nfront = 0;
if (pque->nfront == pque->nrear)
pque->bisempty = true;
return true;
}
}
/*二叉树的层次遍历并判断是否为完全二叉树*/
bool leveltraverse(node *proot)
{
bool bresult = true;
bool bcomfine = false;
node *pcurnode;
queue que;
if (proot == null)
return true;
initqueue(&que,1024); /*这里不考虑队列溢出,在应用中应根据实际情况使用合适
的队列*/
inqueue(&que,proot);
while (outqueue(&que,&pcurnode))
{
if (!pcurnode->pleft && pcurnode->pright)
{
bresult = false;
break;
}
if (bcomfine && (pcurnode->pleft || pcurnode->pright))
{
bresult = false;
break;
}
if (pcurnode->pleft)
inqueue(&que,pcurnode->pleft);
if (pcurnode->pright)
inqueue(&que,pcurnode->pright);
else
bcomfine = true;
}
return bresult;
}
/*简单的测试环境*/
/* 从键盘缓冲区中读取一个不为空格且不为回车的字符 */
char getnextchar(void)
{
char ch;
do
{
ch = getchar();
} while (ch == || ch == /n);
return ch;
}
/*利用前序遍历序列建立二叉树。扩充结点用‘*’代表。前序序列从键盘输入*/
void createtree(node *root)
{
root->pleft = root->pright = null;
if (root->data != *) /* 如果不为扩充结点, 要建立左结点和右结点 */
{
root->pleft = (node *)malloc(sizeof(node));
root->pleft->data = getnextchar();
createtree(root->pleft);
root->pright = (node *)malloc(sizeof(node));
root->pright->data = getnextchar();
createtree(root->pright);
}
}
/*除去*结点*/
void trimtree(node *proot)
{
if (proot->pleft)
if (proot->pleft->data == *)
{
free(proot->pleft);
proot->pleft = null;
}
else
trimtree(proot->pleft);
if (proot->pright)
if (proot->pright->data == *)
{
free(proot->pright);
proot->pright = null;
}
else
trimtree(proot->pright);
}
void main()
{
node root;
root.data = getnextchar();
createtree(&root);
trimtree(&root);
printf("%d/n",leveltraverse(&root));
}