http://www.cnblogs.com/xqzt/archive/2012/12/27/5637134.html#top
AOV网络---拓扑排序
前面说了两个有环的应用
有环->最小生成树(普利姆算法,克鲁斯卡尔算法);
有环->最短路径(迪杰斯特拉算法,弗洛伊德算法);
现在我们说下没环的图
在一个有向图中,用顶点表示活动,用边表示顶点活动之间的优先关系,这样的网我们叫AOV网(Activity On Vertex Network)
设G(V,E) 为有向图 如Vi->Vj有路径 则排序中顶点 Vi必须在Vj之前 我们称这样的排序为 拓扑排序拓扑排序: 就是对一个有向图构造拓扑排序的过程。构造时两种情况 一种是顶点全部输出则为AOV网,二种是顶点数少则说明存在回路。
如下图表示这7个顶点活动之间的先后顺序
AOV网络的用途---拓扑排序
我们经常用有向图来描述一个工程或系统的进行过程。一般来说,一个工程可以分为若干个子工程,只要完成了这些子工程,就可以导致整个工程的完成。
AOV网络若用于教学计划的制定,可以解决:哪些课程是必须先修的,哪些课程是可以并行学习的。1.使用邻接矩阵实现拓扑排序
1、找到全为零的第j 列,输出j
2、将第j 行的全部元素置为零
3、找到全为零的第k列,输出k
4、将第k行的全部元素置为零
…………………反复执行3、4;直至所有元素输出完毕。
2.使用邻接表实现拓扑排序
从AOV网选择入度为0的顶点输出,然后删除此顶点以及以此顶点为尾的弧,重复执行此步骤,直到输出全部顶点或者 AOV网中不存在入度为0的顶点。
由于算法中药查找入度为0的顶点 因此我们在原来顶点表结构中增加一个入度域in
indata firstedge
bool TopoSort(Gadjlist G)
{
int count;//存储输出顶点的个数
int top = 0;
int* stack = new int[G.numV];//设立一个栈来存入度为0的数据
for(int i=0;i<G.numV;i++)
{
if(G->adjlist[i].in == 0)//将in=0的全部入栈
{
stack[top++] = i;//入栈
}
}
while(top != 0)//当栈中
{
int gettop = stack[--top];//出栈
cout<<G.adjlist[gettop].data<<" ";//打印此顶点
cout++;//统计输出顶点个数
for(EdgeNode* e= G.adjlist[gettop].firstedge; e; e=e->next)
{// <span style="line-height: 28.8px; font-family: SimSun;">此循环是将已经打印度为0的边值in</span>减1
int k= e->adjvex;
if(! (--G.adjlist[k].in))//将K号顶点的邻接点入度-1;
{
stack[top++] = k;
}
}
}
delete [] stack;
if(cout<G.numV)
{
return false;//如果count<顶点数则说明存在环
}
else
{
return true;
}
}
用来判断有向图中是否存在环,工业先后顺序,多道工序。时间复杂度为O(N+E); 拓扑排序结果不唯一!!!