拓扑排序——附模版伪代码和完整代码

1 拓扑排序

1.1 概念

  • 有向无环图(Directed Acyclic Graph,DAG):有向图中任何一个顶点都无法通过一些有向边回到自身。
  • 拓扑排序:将有向无环图G的所有顶点排成一个线性序列,使得对图G中任意两个顶点u、v,如果存在边u->v,那么在序列中u一定在v的前面。
  • 具体含义见下图:
    在这里插入图片描述
    在这里插入图片描述

1.2 计算步骤

  • 1 定义一个队列Q,并把所有入队为0的结点加入队列;
  • 2 取队首结点,输出。然后删除所有从它出发的边,并令这些边到达顶点的入度减1,如果某个顶点的入度为0,则将其加入队列;
  • 3 反复进行2操作,直到队列为空。如果队列为空时,入过队的结点数目恰好为N,说明拓扑排序成功,图G为有向无环图;否则拓扑排序失败,图中有环。

1.3 实现代码

const int MAXN = 1000;
vector<int> G[MAXN];
int n, m;//顶点数、边数
int inDegree[MAXN];//入度

bool topologicalSort(){
    int num = 0;
    queue<int> q;
    for (int i = 0; i < n; ++i)
    {
        if(inDegree[i] == 0){
            q.push(i);    //将所有入度为0的顶点入队
        }
    }

    while(!q.empty()){
        int u = q.front();
        //printf("%d", u);//此处可输出顶点u,作为拓扑序列中的顶点
        q.pop();
        
        for (int i = 0; i < G[u].size(); ++i)
        {
            int v = G[u][i];//u的后继结点v
            inDegree[v]--;//顶点v的入度减1
            if(inDegree[v] == 0){//顶点v的入度减为0,则入队
                q.push(v);
            }
        }
        G[u].clear();//清空顶点u的所有出边(如无必要可不写)
        num++;//加入拓扑序列的顶点数加1
    }

    if(num == n) return true;//给的图是有向无环图
    else return false;  //给定的图中有还
}
发布了378 篇原创文章 · 获赞 52 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_33375598/article/details/104433347
今日推荐