图论(四)--拓扑排序

来源:互联网 发布:学美工设计培训班 编辑:程序博客网 时间:2024/05/29 09:35

基于算法导论图算法-拓扑排序

  • 题目描述
  • 问题分析
  • 源代码
  • 结果截图

    题目描述

    对有向无环图进行拓扑排序(使用队列和DFS分别进行实现)

    问题分析

    1、使用队列进行实现:不断寻找入度为0的点;

    2、使用DFS进行实现:DFS图后根据各顶点发现时间逆序排列,即可得到拓扑排序(证明可以看算法导论第22章22.3节拓扑排序)

伪代码

队列实现
队列实现

DFS实现
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");    }}

结果截图

两种方式实现的结果不是完全相似,但均是拓扑排序的正确序列,使用链状图结构进行测试可得到完全一致的效果

这里写图片描述

0 0