1、概念

活动的网(AOV网):在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,我们成为AOV网(Activity On Vertext Network)。

AOV网中的弧表示活动之间存在的某种制约关系。

拓扑序列:设G=(V,E)是一个具有n个顶点的有向图,V中的顶点序列v1,v2,……,vn,满足若从顶点vi到vj有一条路径,则在顶点序列中顶点vi必再顶点vj之前。则我们称这样的顶点序列为一个拓扑序列。

拓扑排序:就是对一个有向图构造拓扑序列的过程。

2、应用范围

拓扑排序常用来确定一个依赖关系集中,事物发生的顺序。例如,在日常工作中,可能会将项目拆分成A、B、C、D四个子部分来完成,但A依赖于B和D,C依赖于D。为了计算这个项目进行的顺序,可对这个关系集进行拓扑排序,得出一个线性的序列,则排在前面的任务就是需要先完成的任务。

3、实现方法:

(1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它。

(2)从网中删去该顶点,并且删去从该顶点发出的全部有向边。

(3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止。

4、条件

图使邻接表存储。

图的拓扑排序_第1张图片

此时我们需要为顶点表增加一个入度域in,表示入度个数。

5、code

/*顶点表结点*/
typedef struct VertexNode
{
    int in;    /*顶点入度*/
    int data;    /*顶点域,存储顶点信息*/
    EdgeNode *firstedge;    /*边表头指针*/
}EdgeNode;


/*边表结点*/
typedef struct EdgeNode
{
    int adjvex;    /*邻接点域,存储该顶点对应的下标*/
    int weight;    /*用于存储权值,对于非网图可以不需要*/
    struct EdgeNode *next;    /*链域,指向下一个邻接点*/
}VertexNode,AdjList[MAXVEX];

typedef struct
{
    AdjList adjList;
    int numVertexes,numEdges;    /*图中当前顶点数和边数*/
}graphAdjList,*GraphAdjList;

/*拓扑排序,若GL无回路,则输出拓扑排序序列并返回OK,若有回路返回ERROR*/
Status TopologicalSort(GraphAdjList GL)
{
    EdgeNode *e;
    int i,k,gettop;
    int top=0;    /*用于栈指针下标*/
    int count=0;    /*用于统计输出顶点的个数*/
    int *stack;    /*建栈存储入度为0的顶点*/
    stack=(int *)malloc(GL->numVertexes * sizeof(int));
    for(i=0;inumVertexes;i++)
        if(GL->adjList[i].in==0)
            stack[++top]=i;    /*将入度为0的顶点入栈*/
    while(top!=0)
    {
        gettop=stack[top--];    /*出栈*/
        printf("%d —> ",GL->adjList[gettop].data);    /*打印此顶点*/
        count++;    /*统计输出顶点数*/
        for(e=GL->adjList[gettop].firstedge;e;e=e->next)
        {
            /*对此顶点弧表(边表)进行遍历*/
            k=e->adjvex;
            if(!(--GL->adjList[k].in))    /*将k顶点邻接点的入度减1后值为0,则入栈*/
                stack[++top]=k;
        }
    }
    if(countnumVertexes)    /*如果count小于顶点数,说明存在环路*/
        return ERROR;
    else
        return OK;
}