拓扑排序

这一生的挚爱 提交于 2020-03-01 20:25:34

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)。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!