拓扑排序
拓扑排序(topological-sort)是指由某个集合上的一个偏序得到该集合上的一个全序的操作。拓扑排序常用来确定一个依赖关系集中,事物发生的顺序。拓扑排序是对有向无环图的顶点的一种排序,它使得如果存在一条从顶点A到顶点B的路径,那么在排序中B出现在A的后面。
简单来讲就是我要做ABCD四件事,如果想要完成A,那么需要先完成B和C,而B需要先做D,C也需要先做D,那么我们可以轻易得到一个序列D->B->C->A可以遍历到图里的所有结点。
其实由此不难得出拓扑排序的思路。非常简单,先找入度为0的结点v,每次找一个一共找n次,degree[v]–(让v的入度变成-1,不重复判断),并同时所有和v相连的结点入度-1。
void toposort(int map[MAX][MAX],int indegree[MAX],int n)
{
int i,j,k;
for(i=0;i<n;i++) //遍历n次
{
for(j=0;j<n;j++) //找出入度为0的节点
{
if(indegree[j]==0)
{
indegree[j]--;
cout<<j<<endl;
for(k=0;k<n;k++) //删除与该节点关联的边
{
if(map[j][k]==1)
{
indegree[k]--;
}
}
break;
}
}
}
}
其实不难看出这也是一个逐层搜索的过程,bfs思想的体现。
void topo()
{
int i,u;
top=0;
queue<int> Q; //队列
for (i=1;i<=n;i++) //找到入度为0的结点入队,可能不止一个
if (gin[i]==0)
Q.push(i);
while(!Q.empty()) //队列不为空就一直循环
{
u=Q.front();Q.pop(); //队首出队
c[top++]=u;
for (i=1;i<=n;i++)
{
if (g[u][i])
{
gin[i]--; //从u出发的结点入度-1
if (gin[i]==0)
Q.push(i);//如果入度为0就加入队列
}
}
}
}