摘要:本文简要介绍了拓扑排序算法的原理,并给出了基于邻接矩阵实现的拓扑排序c++源码
关键字:拓扑排序,topological sort,AOV网络
最近在论坛上看到一个百度的笔试题,大概意思是给定N个有依赖关系但是没有循环依赖的源码文
件,要求给这些源文件确定一个合适的编译顺序。这个跟选修课程的先后顺序一样,是个典型的拓扑排序
问题。拓扑排序针对的是AOV网络,即Activity on Vertex Network,这种模型在有向图中若以顶点表示活
动,有向边表示活动之间的先后关系。下面给出这类问题的一种基于邻接矩阵
的通用算法:
1)用一个矩阵Matrix[N][N]保存结点的前驱关系,即如果i是j的前驱结点,则Matrix[i][j]=1,
否则,Matrix[i][j]=0;(其中i表示行,j表示列)
2) 用一个以为数组into[N]保存每个节点的入度;
3) for i = 1 to N //循环N次
j = 0;
while(j < N && into[j] != 0) j++;//寻找入度为0的结点j
输出节点j
将into[j]设为N以免再次输出;
for k = 1 to N //遍历矩阵的第j行
if (Matrix[j][k] == 1) into[k]–;
该算法的时间复杂度是O(N^2)。
算法的c++实例源码如下:(VC++6.0编译测试通过)
/*
* 拓扑排序
* 使用邻接矩阵表示图
*/
#include
using namespace std;
#define N 9
/* global data */
//如果i是j的直接前驱,matrix[i][j] = true, 否则martix[i][j] = false;
//其中i表示行,j表示列
int matrix[N][N]=
{
0,0,1,0,0,0,0,1,0,
0,0,1,1,1,0,0,0,0,
0,0,0,1,0,0,0,0,0,
0,0,0,0,0,1,1,0,0,
0,0,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,1,
0,0,0,0,0,0,1,0,0
};
int into[N];
/* functions declaration */
void get_into_degree(int n);
void toposort(int n);
int main(int argc, char* *argv)
{
get_into_degree(N);
toposort(N);
system("pause");
return 0;
}
/* functions definition */
void get_into_degree(int n)
{
for(int j = 0; j < n; ++j)
{
into[j] = 0;
for(int i = 0; i < n; ++i)
{
if(matrix[i][j] == 1)
{
into[j]++;
}
}
}
}
void toposort(int n)
{
//需要输出n个结点,排序结束
for(int i = 1; i <= n; ++i)
{
int j = 0;
while(j < n && into[j] != 0) j++;
//找到度为0的点
cout << j + 1 << " ";
//更新度
into[j] = N ;//设结点j为最大度,以免再次输出j
for(int k = 0; k < n; ++k)
{
if(matrix[j][k] == 1)
{
into[k]--;
}
}
}
}
参考资料 [1]信息技术竞赛辅导,作者不详
[2]百度百科,拓扑排序 |