拓扑排序
基本概念
拓扑序:如果图中从V到W有一条有向路径,则V一定排在W之前。满足此条件的顶点序列称为一个拓扑序,那么拓扑排序就是获得一个拓扑序的过程。另外,如果有合理的拓扑序,则必定是有向无环图。
拓扑排序算法
下面介绍一个比较好的拓扑排序算法
伪代码如下:
void TopSort(){
for(图中每个顶点V)
if(Indegree[V]==0)
Enqueue(Q,V);
while(!IsEmpty(Q)){
V=Dequeue(Q);
输出V,或者记录V的输出序号;
cnt++;
for(V的每个邻接点W)
if(--Indegree[W]==0)
Enqueue(Q,W);
}
if(cnt!=|V|)
ERROR("图中有回路");
}
C语言实现如下:
bool TopSort(LGraph Graph, Vertex TopOrder[]){ //对Graph进行拓扑排序,TopOrder[]顺序存储排序后的顶点下标
int Indegree[MaxVertexNum],cnt;
Vertex V;
PtrToAdjVNode W;
Queue Q=CreateQueue(Graph->Nv);
for(V=0;V<Graph->Nv;V++) //初始化Indegree[]
Indegree[V]=0;
for(V=0;V<Graph->Nv;V++) //遍历图,得到Indegree[]
for(W=Graph->G[V].FirstEdge;W;W=W->Next)
Indegree[W->AdjV]++; //对有向边<V,W->AdjV>累计终点的入度
for(V=0;V<Graph->Nv;V++)
if(Indegree[V]==0) //将所有入度为0的顶点入队
AddQ(Q,V);
cnt=0;
while(!IsEmpty(Q)){
V=DeleteQ(Q); //弹出一个入度为0的顶点
TopOrder[cnt++]=V; //将V存为结果序列的下一个元素
for(W=Graph->G[V].FirstEdge;W;W=W->Next) //对于V的每一个邻接点W->AdjV
if(--Indegree[W->AdjV]==0) //若删除V使得W->AdjV的入度为0
AddQ(Q,W->AdjV); //则将W->AdjV入队
}
if(cnt!=Graph->Nv) //图中有回路
return fasle;
else
return true;
}
时间复杂度T=O(|V|+|E|),此算法也可以用来检测有向图是否是无环图。