1,定义
(1)AOV网:在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,我们称为AOV网。AOV网中的弧表示活动之间存在的某种制约更新。其中AOV网中不能存在回路。
(2)拓扑排序:对一个有向无环图G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。
例如:设G=(V,E)是一个具有n个顶点的有向图,V中的顶点序列v1,v2,…,vn,满足若从顶点vi到vj有一条路径,则在顶点序列中顶点vi必在vj之前,则我们称这样的顶点序列为一个拓扑序列。
说明:所谓拓扑排序其实就是对一个有向图构造拓扑序列的过程。
2,拓扑排序算法
从AOV网中选择一个入度为0的顶点输出,然后删除此顶点,并删除以此顶点为尾的弧,重复操作指导输出全部顶点或者AOV网中不存在入度为0的顶点为止。
说明:前面的最小生成树和最短路径都是使用的 邻接矩阵 ,由于拓扑排序过程需要删除顶点,所以我们使用 邻接表 会更加方便,而且需要在顶点表中加入入度域,我们会根据顶点的入度决定是否删除。
例如,我们将下面的AOV网转邻接表:
对于转换的实现,我们需要借助栈或者队列来实现,都可以。
3,拓扑排序代码实现
Status TopologicalSort(AdjGraphList AG)
{
EdgeNode* e;
int i, j,k, gettop;
int count = 0; //用于统计输出顶点个数
int top = -1; //这是我们要创建的栈的指针
int *stack = (int*)malloc(sizeof(int)*AG.numVertexes); //这是我们创建的临时栈
//最开始将所有入度为0的顶点入栈
for (i = 0; i < AG.numVertexes; i++)
if (!AG.adjlist[i].in)
stack[++top] = i;
//下面进入主循环,直到栈中无数据结束(全部顶点输出,或者剩余的成环,入度都不为0)
while (top!=-1)
{
//出栈数据
gettop = stack[top--]; //出栈
printf("%c -> ", AG.adjlist[gettop].data);
count++;
//对他出栈数据的所有邻接点的入度减一
for (e = AG.adjlist[gettop].firstedge; e;e=e->next)
{
k = e->adjvex;
if (!(--AG.adjlist[k].in))
stack[++top] = k;
}
}
printf("\n");
//进行判断,若是count小于顶点数,则有环
if (count < AG.numVertexes)
return ERROR;
return OK;
}
时间复杂度:
对一个具有n个顶点e条弧的AOV网,我们几乎要对每个顶点进行出入栈操作,时间复杂度为O(n),我们要对每个顶点的入度减一,就是减少一条边,时间复杂度取决于边数,为O(e)。所以整个算法时间复杂度为O(n+e)。
来源:CSDN
作者:Ysming88
链接:https://blog.csdn.net/m0_45861545/article/details/104579059