由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
顶点表活动,弧表示活动间先后依赖关系的有向图。
用以表示工程或系统的施工计划,可据此判断工程是否可以顺利进行。网中应存在一覆盖全部顶点的序列(全序),在该序列中顶点出现的顺满足网中的先后顺序(偏序)。一个全序就对应一个合法的完整工程。
输入:创建图。
输出:拓扑排序序列。
运行结果:
若得到一个含全部顶点的拓扑有序序列则说明工程可顺利开展,不存在则说明图中存在有向回路,不合理。
算法思想:
1、从有向图中选取一没有前驱的顶点输出之;
2、从图中删除此顶点即所有从其出发的弧。
3、重复上述两步,至图空,或图不空但不存在无前驱的顶点(得一有向环).
实现的话,入度0顶点入栈,{删除{出栈并据此更新入度},零入度者入栈}重复至栈空,若弹出的 元素个数小于顶点数说明存在回路。计划不合理。
算法实现:
邻接表存储:
Status TopologicalSort(MGraph G,SqStack &T){
/*拓扑排序
将度为0的顶点的入队 出队 更新后继点入度 若入度为0 则入队
根据输出结点数量判断是否合理
各点ve初始化为0 计算入度 求各顶点最早到达时间计入全局数组ve*/
int InDegree[MVNUM],i,count=0,j; //count对输出的点进行计数
bool a[MVNUM]; //判断顶点是否输出过
LinkQueue Q;
InitQueue(Q);
InitStack(T);
memset(InDegree,0,sizeof(InDegree));
memset(a,0,sizeof(a));
FindInDegree(G,InDegree);
for(i=0;i<G.vexnum;i++){
if(!InDegree[i]){
EnQueue(Q,i);
a[i]=TRUE;
}
}
while(!QueueEmpty(Q)){
DeQueue(Q,i);
Push(T,i);
OutPutElem(G.vexs[i]);
count++;
for(j=0;j<G.vexnum;j++){
if(G.arcs[i][j].adj!=INFINITY){ //如果有弧
InDegree[j]--;
}
if(!a[j]&&!InDegree[j]) {
EnQueue(Q,j);
a[j]=TRUE;
}
}
}
if(count==G.vexnum)
return OK;
else
return ERROR;
}
计算各项点的入度.
void FindInDegree(MGraph G,int InDegree[MVNUM]){
//计算各项点的入度
for(int i=0;i<G.vexnum;i++)
for(int j=0;j<G.vexnum;j++)
if(G.arcs[j][i].adj!=INFINITY)
InDegree[i]++;
}
邻接表存储
Status TopologicalSort(ALGraph G,SqStack &T){
/*拓扑排序
将度为0的顶点入队 出队 更新后继结点的入度 若入读为0 则入队
根据输出结点数量判断是否合理
各点ve初始化为0 计算入度 求各顶点最早到达时间计入全局数组ve*/
int InDegree[MVNUM],i,k,count=0; //count对输出的结点进行计数
memset(InDegree,0,sizeof(InDegree));
FindInDegree(G,InDegree);
LinkQueue Q;
InitQueue(Q);
InitStack(T);
for(i=0;i<G.vexnum;i++){
if(!InDegree[i])
EnQueue(Q,i);
}
while(!QueueEmpty(Q)){
DeQueue(Q,i);
Push(T,i);
count++;
OutPutElem(G.vertices[i].data);
for(ArcNode *p=G.vertices[i].firstarc;p!=NULL;p=p->nextarc){
k=p->adjvex;
InDegree[k]--;
if(!InDegree[k])
EnQueue(Q,k);
}
}
if(count==G.vexnum)
return OK;
else
return ERROR;
}
计算各个结点的入度.
void FindInDegree(ALGraph G,int InDegree[]) {
//计算各个结点的入度
int k,i;
for(i=0;i<G.vexnum;i++)
for(ArcNode *p=G.vertices[i].firstarc;p!=NULL;p=p->nextarc){
k=p->adjvex;
InDegree[k]++;
}
}