基于算法导论图算法-拓扑排序
- 题目描述
- 问题分析
- 源代码
结果截图
题目描述
对有向无环图进行拓扑排序(使用队列和DFS分别进行实现)
问题分析
1、使用队列进行实现:不断寻找入度为0的点;
2、使用DFS进行实现:DFS图后根据各顶点发现时间逆序排列,即可得到拓扑排序(证明可以看算法导论第22章22.3节拓扑排序)
伪代码
队列实现
DFS实现
源代码
int topSort_queue(Graph G);//队列实现
void topSort_dfs(Graph G);//dfs实现
void print_order_queue(Graph G);//打印拓扑排序序列(queue)
void print_order_dfs(Graph G);//打印拓扑排序序列(dfs)
int TopOrder[VertexNum];
void print_order_queue(Graph G) {
for (int i = 0; i < G->vexnum; i++) {
printf("%d ",TopOrder[i]);
}
printf("\n");
}
int topSort_queue(Graph G) {//用队列实现拓扑排序,不断寻找入度为0的顶点
memset(TopOrder, -1, sizeof(TopOrder));
queue<int> Q;
int count = 0;
PtrToNode ptr;
for (int i = 0; i < G->vexnum; i++) {//将入度为0的顶点进队列
if (G->vertices[i].in_degree == 0) Q.push(i);
}
while (!Q.empty()) {
int u = Q.front();
TopOrder[count++] = u;
Q.pop();
for (ptr = G->vertices[u].adjto; ptr != NULL; ptr = ptr->next) {//将出队列的顶点相邻的顶点入度减一
if (--G->vertices[ptr->adjvex].in_degree == 0) Q.push(ptr->adjvex);
}
}
if (count != VertexNum) return 0;
else return 1;
}
struct num_finTime {//基于dfs实现拓扑排序时用到的数据结构
int number;
int finTime;
};
struct num_finTime TopOrder1[VertexNum];//序列
bool cmp(const struct num_finTime &a1, const struct num_finTime &a2) {
return a1.finTime > a2.finTime;
}
void print_order_dfs(Graph G) {
for (int i = 0; i < G->vexnum; i++) {
printf("%d ", TopOrder1[i].number);
}
printf("\n");
}
void topSort_dfs(Graph G) {
DFS(G);//dfs具体代码可以参考[图论(三)-深度优先搜索(DFS)](http://blog.csdn.net/deep_kang/article/details/70880024)
for (int i = 0; i < G->vexnum;i++){
TopOrder1[i].number = i;
TopOrder1[i].finTime = G->vertices[i].finish_time;
}
sort(TopOrder1, TopOrder1 + VertexNum, cmp);//此处可以优化,需要在DFS代码中添加一些细节,在每次结点结束时,将该节点加入到链表头,这样可使算法效率提高(省去了这次排序)
}
int main() {
CreateRandomDirectGraph();
Graph G = CreateDirectGraph();//为测试方便,10个顶点
print_graph(G);//打印图
//print_VertexDegree(G);//打印顶点度数
//print_EdgeWeight(G);//打印边权
printf("拓扑排序:\n");
if (topSort_queue(G)) {//如果返回1,证明图是有向无环图;除了可以使用拓扑排序求图是否有环,还可以使用DFS(做一点小的改动)具体可参见[判断一个图是否有环 有向图 无向图](http://www.cnblogs.com/xwdreamer/archive/2011/06/11/2297008.html)
print_order_queue(G);
topSort_dfs(G);//此处测试dfs实现的代码
print_order_dfs(G);
}
else {
printf("失败,此图不满足有向无环图。\n");
}
}
结果截图
两种方式实现的结果不是完全相似,但均是拓扑排序的正确序列,使用链状图结构进行测试可得到完全一致的效果