//判定一棵二叉树是否为完全二叉树
bool Is(BiTree b)
{
InitQueue(Q);
BiTree p;
if(b==NULL) //空树为满二叉树
return true;
EnQueue(Q,b);//将根节点入队
while(!IsEmpty(Q)) //如果队列不为空
{
DeQueue(Q,p); //出队首元素
if(p) //如果出队元素不为空,将其左孩子和右孩子分别入队
{
EnQueue(Q,p->lchild);
EnQueue(Q,p->rchild);
}
else //如果出队元素为空,检查其后是否有非空结点
{
while(!IsEmpty(Q))//如果出队元素为空,但是队列不空,查看队列中是否有非空结点,若有则不是完全二叉树
DeQueue(Q,p);
if(p) //结点非空,则二叉树为非完全二叉树
return false;
}
}
return true;
}
/*
完全二叉树的定义是:具有n个结点的完全二叉树与满二叉树中的编号从1~n的结点一一对应。
算法思想:
采用层次遍历的方法,让所有的结点入队(包括空结点),当遇到空节点的时候判断其后继是否还有非空结点,若有则为非完全二叉树
*/
//查找p,q的最近公共祖先结点r
typedef struct
{
BiTree t;
int tag; //tag=0表示左子女已被访问,tag=1表示右子女已被访问
}stack;
stack s[],s1[]; //栈的容量足够大
BiTree Ancestor(BiTree T,BiTNode *p,BiTNode *q)
{
top = 0;
BiTree bt = T;
while(bt!=NULL||top>0) //树不空且栈不空
{
while(bt!=NULL&&bt!=p&&bt!=q) //结点入栈
{
top++;
s[top].t = bt;
s[top].tag = 0;
bt = bt->lchild; //沿左分支向下
}
while(top!=0&&s[top].tag==1)
{ //假定p在q的左侧,遇到p时,栈中元素均为p的祖先
if(s[top].t==p)
{
for(int i=1;i<=top;i++) //将栈s的元素都转到辅助栈s1中去
{
s1[i] = s[i];
top1 = top;
}
}
if(s[top].t==q) //找到q结点
{
for(int i=top;i>0;i--) //将栈中元素的树结点到s1中去匹配
{
for(int j=top1;j>0;j--)
{
if(s[i].t==s1[j].t)
return s[i].t; //p和q的最近公共祖先已找到
}
top--; //退栈
}
if(top!=0)
{
s[top].tag=1;
bt = s[top].t->rchild; //沿右分支向下遍历
}
}
}
return NULL; //p和q没有公共祖先
}