树的各种算法大集锦2

//判定一棵二叉树是否为完全二叉树
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没有公共祖先
}

 

posted @ 2019-08-13 20:08  小孢子  阅读(513)  评论(0编辑  收藏  举报