拓扑排序

来源:互联网 发布:粒子群算法应用于实际 编辑:程序博客网 时间:2024/04/30 04:23

拓扑排序是对有向无圈图的顶点的一种排序,它使得如果存在一条从vi到vj的路径,那么在排序中vj出现在vi的后面。

显然,如果图中存在圈,那么拓扑排序是不可能完成的,因为对于圈上的两个顶点v和w,v先于w的同时w先于v,是矛盾的。

一个简单的拓扑排序的算法:

voidTopsort(Gragh G){int Counter;Vertex V,W;for(Counter = 0; Counter < NumVertex; Counter++){V = FindNewVertexOfIndegreeZero(); //寻找一个尚未被分配拓扑编号的入度为0的顶点if(V == NotAVertex){Error("Gragh has a cycle");break;}TopNum[V] = Counter;for each W adjacent to VIndegree[W]--;}}
一个简单的求拓扑排序的算法是先找出任意一个没有入边的顶点,然后我们显示出该顶点,并将它和它的边一同从图中删除。

我们把顶点v的入度定义为边(u,v)的条数,计算图中所有顶点的入度,设Indegree数组被初始化且图被读入一个邻接表中。

但是这种方法虽然简单,也很耗时,因为FindNewVertexOfIndegreeZero()是对Indegree数组顺序扫描。


另一种更好的办法是将所有(未分配拓扑编号)入度为0的顶点放在一个特殊的盒子中而避免了一遍又一遍的扫描。

我们可以使用一个队列,首先对每一个顶点计算他的入度。然后将所有入度为0的顶点放入一个初始的空的队列中。

当队列不为空时,删除一个项v,并将与其邻接的所有顶点的入度减1.只要一个顶点的入度降为0,就把该顶点放入

队列中。

伪代码实现如下

voidTopsort( Gragh G){Queue Q;int Counter = 0;Vertex V,W;Q = CreateQueue(NumVertex); MakeEmpty(Q);for each vertex Vif(Indegree[V] == 0)EnQueue(V, Q);while( !Empty(Q)){V = DeQueue(Q);TopNum[V] = ++Counter;    //Assign next numberfor each W adjacent to Vif( --Indegree[W] == 0)EnQueue(W, Q);}if(Countrt != NumVertex)Error("Gragh has a cycle");DisposeQueue(Q);        //free the memory}}