数据结构——拓扑排序

1. 定义:给出有向图G=(V,E), 对于V中的顶点的线性序列(v1,v2,...,vn), 如果满足如下条件: 若在G中从顶点 vi 到vj有一条路经,  则在序列中顶点vi必在顶点vj之前; 则称该序列为G的一个拓扑序列

构造有向图的一个拓扑序列的过程称为拓扑排序

2. 实际意义:如果按照拓扑序列中的顶点次序进行每一项活动,就能够保证在开始每一项活动时,他的所有前驱活动均已完成,从而使整个工程顺序执行。

3. 说明:

  1. 在AOV网中, 若不存在回路, 则所有活动可排成一个线性序列,使得每个活动的所有前驱活动都排在该活动的前面,那么该序列为拓扑序列。
  2. 拓扑排序列不是唯一的。

4. 拓扑排序方法:

  1. 在AOV网中选一个入度为0的顶点( 没有前驱) 且输出之;
  2. 从AOV网中删除此顶点及该顶点发出来的所有有向边;
  3. 重复(1)、(2)两步, 直到AOV网中所有顶点都被输出或网中不存在入度为0的顶点。

具体实现过程:

拓扑排序算法:时间复杂度:O(n+e)

bool Topological(ALGraph G)
{ 
    //有向图采用邻接表存储结构
    //若G无回路, 则输出G的顶点的一个拓扑排序算法并返回OK, 否则ERROR
    initStack(&S); //初始化栈
    for(i=0;i<G.vernum;++i)
        if(! G.adjlist[i].indegree) push(&S,i); //入度为0的顶点入栈
    count=0; //输出顶点计数器
    while(!StackEmpty(S))
    {
        pop(&S,&i); //顶点 i 出栈
        printf(i,G.vertices[i].data); //输出顶点i
        ++count; //计数器加1
        for (p=G.adjlist[i].firstarc; p; p=p->nextarc)
        { 
            //顶点i的每个邻接点(以i为狐尾的)的入度减 1
            k=p->adjvex;
            if (!(--G.adjlist[k].indegree)) //k的减1, 若入度为0入栈
                push(&S,k);
        } //for
    }//while
    if (count<G.vernum)
        return false; //存在回路
    else
        return true;
}//Topological

猜你喜欢

转载自blog.csdn.net/weixin_42562514/article/details/85235021