拓扑排序
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若 ∈E(G),则u在线性序列中出现在v之前。
一般应用
拓扑排序常用来确定一个依赖关系集中,事物发生的顺序。例如,在日常工作中,可能会将项目拆分成A、B、C、D四个子部分来完成,但A依赖于B和D,C依赖于D。为了计算这个项目进行的顺序,可对这个关系集进行拓扑排序,得出一个线性的序列,则排在前面的任务就是需要先完成的任务。
实现的基本方法
拓扑排序方法如下:
(1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.
(2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.
(3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止.
代码如下:
#include "GraphLink.h"
#include <iostream>
int A[N][N] = {
//C0 C1 C2 C3 C4 C5 C6 C7 C8
/*C0*/ 0, 0, 1, 0, 0, 0, 0, 1, 0,
/*C1*/ 0, 0, 1, 1, 1, 0, 0, 0, 0,
/*C2*/ 0, 0, 0, 1, 0, 0, 0, 0, 0,
/*C3*/ 0, 0, 0, 0, 0, 1, 1, 0, 0,
/*C4*/ 0, 0, 0, 0, 0, 1, 0, 0, 0,
/*C5*/ 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*C6*/ 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*C7*/ 0, 0, 0, 0, 0, 0, 0, 0, 1,
/*C8*/ 0, 0, 0, 0, 0, 0, 1, 0, 0
};
//***************************************************************
//队列实现的图拓扑排序
void topSort(Graph &g)
{
for(int i = 0; i < g.verticesNum();i++)
{
g.mark[i] = UNVISITED;//初始化Mark数组
}
queue<int> que;
for(int i = 0; i < g.verticesNum();i++)
{
if(g.indegree[i] == 0)//图中入度为0的顶点入队
{
que.push(i);
}
}
while(!que.empty())
{
int v = que.front();
que.pop();
cout << "C" << v << "\t";
g.mark[v] = VISITED;
for(Edge edge = g.firstEdge(v); g.isEdge(edge); edge = g.nextEdge(edge))
//所有与之相邻的点入度-1
{
g.indegree[g.toVertex(edge)]--;
if(g.indegree[g.toVertex(edge)] == 0)
{
que.push(g.toVertex(edge));//入度为0的顶点入队
}
}
}
for(int i = 0; i < g.verticesNum();i++)
{
if(g.mark[i] == UNVISITED)
{
cout << "图中有环" << endl;
break;
}
}
}
int main()
{
GraphLink<ListUnit> graphLink(N); // 建立图
graphLink.initGraph(graphLink, A,N); // 初始化图
topSort(graphLink);
system("pause");
return 0;
}