树的各种算法大集锦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没有公共祖先 }