拓扑排序

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

在讲解拓扑排序之前,我们先介绍一个概念,AOV网:
通常,我们把顶点表示活动、边表示活动间先后关系的有向图称做顶点活动网(Activity On Vertex network),简称AOV网。
2、拓扑排序的步骤:
由AOV网构造拓扑序列的拓扑排序算法主要是循环执行以下两步,直到不存在入度为0的顶点为止。
(1) 选择一个入度为0的顶点并输出之;
(2) 从网中删除此顶点及所有出边。

!!!循环结束后,若输出的顶点数小于网中的顶点数,则输出“有回路”信息,否则输出的顶点序列就是一种拓扑序列。[2]

3、一个简单的例子理解拓扑排序:
拓扑排序_第1张图片

要对这些课程进行排序,当是比较少的课程时,我们可以直接理清楚课程的顺序,但是当课程达到很多时,我们就可以借助图来进行排序,首先我们需要建立一个图,在这里很容易想到,将课程作为图的顶点,在这里我们把边v->w看做v是w的预修课。
根据这个思路建立了如图所示的图:
拓扑排序_第2张图片

根据建立的图进行拓扑排序将得到课程的顺序:
c1 c2 c8 c4
c3 c13 c9 c5
c7 c6
c11 c12 c10 c15
c14

通过这个例子,应该对拓扑排序有了更深的理解

4、拓扑排序的代码实现:

bool TopSort( LGraph Graph, Vertex TopOrder[] )
{ /* 对Graph进行拓扑排序,  TopOrder[]顺序存储排序后的顶点下标 */
    int Indegree[MaxVertexNum], cnt;
    Vertex V;
    PtrToAdjVNode W;
       Queue Q = CreateQueue( Graph->Nv );

    /* 初始化Indegree[] */
    for (V=0; VNv; V++)
        Indegree[V] = 0;//顶点的入度

    /* 遍历图,得到Indegree[] */
    for (V=0; VNv; V++)
        for (W=Graph->G[V].FirstEdge; W; W=W->Next)
            Indegree[W->AdjV]++; /* 对有向边AdjV>累计终点的入度 */

    /* 将所有入度为0的顶点入列 */
    for (V=0; VNv; V++)
        if ( Indegree[V]==0 )
            AddQ(Q, V);

    /* 下面进入拓扑排序 */ 
    cnt = 0; 
    while( !IsEmpty(Q) ){
        V = DeleteQ(Q); /* 弹出一个入度为0的顶点 */
        TopOrder[cnt++] = V; /* 将之存为结果序列的下一个元素 */
        /* 对V的每个邻接点W->AdjV */
        for ( W=Graph->G[V].FirstEdge; W; W=W->Next )
            if ( --Indegree[W->AdjV] == 0 )/* 若删除V使得W->AdjV入度为0 */
                AddQ(Q, W->AdjV); /* 则该顶点入列 */ 
    } /* while结束*/

    if ( cnt != Graph->Nv )
        return false; /* 说明图中有回路, 返回不成功标志 */ 
    else
        return true;
}

关于拓扑排序的另一个应用:路径问题,是基于AOE网络解决的,在这里不做详细讲解,感兴趣的可以去搜一下,实现代码稍改一下就可以实现。

你可能感兴趣的:(数据结构与算法)