代码改变世界

拓扑排序

2013-08-13 11:59  北漂男孩  阅读(835)  评论(0编辑  收藏  举报

  1.拓扑序列:设G=(V,E)是一个具有n个顶点的有向图,V中的顶点序列v1, v2, …, vn称为一个拓扑序列,当且仅当满足下列条件:若从顶点vi到vj有一条路径,则在顶点序列中顶点vi必在顶点vj之前。

  2.拓扑排序的规则:

  ⑴ 从AOV网中选择一个没有前驱的顶点并且输出;

  ⑵ 从AOV网中删去该顶点,并且删去所有以该顶点为尾的弧;

  ⑶ 重复上述两步,直到全部顶点都被输出,或AOV网中不存在没有前驱的顶点。 

  3.示例:

  

  4.实现:

  (1)设计数据结构:

   图的存储结构:采用邻接表存储 ,在顶点表中增加一个入度域。

        

   栈S:存储所有无前驱的顶点。

  

  (2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Status TopologicalSort(ALGraph G)
{
    // 有向图G采用邻接表存储结构。
    // 若G无回路,则输出G的顶点的一个拓扑序列并返回OK,否则ERROR。
    SqStack S;
    int count,k,i;
    ArcNode *p;
    char indegree[MAX_VERTEX_NUM];
    FindInDegree(G, indegree);   // 对各顶点求入度indegree[0..vernum-1]
    InitStack(S);
    for (i=0; i<G.vexnum; ++i)       // 建零入度顶点栈S
        if (!indegree[i]) Push(S, i);  // 入度为0者进栈
        count = 0;                       // 对输出顶点计数
        while (!StackEmpty(S))
        {
            Pop(S, i);
            printf(i, G.vertices[i].data);  ++count;  // 输出i号顶点并计数
            for (p=G.vertices[i].firstarc;  p;  p=p->nextarc)
            {
                k = p->adjvex;               // 对i号顶点的每个邻接点的入度减1
                if (!(--indegree[k]))
                    Push(S, k);  // 若入度减为0,则入栈
            }
        }
        if (count<G.vexnum)
            return ERROR;      // 该有向图有回路
        else
            return OK;
}

.......