zoukankan      html  css  js  c++  java
  • 图论算法——思路超清晰的拓扑排序

    最近在学习数据结构与算法分析——C语言描述这本书,话说都买了1年多了都没有看,最近有时间了就捡起来吧。直接上代码:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX_VERTEX_NUM 7
    
    int TopNum[7];
    
    typedef struct EdgeNode    // 邻接顶点
    {
        int adjvertex;
        struct EdgeNode *next;
    }EdgeNode;
    
    typedef struct VertexNode    // 顶点
    {
        int vertex;
        EdgeNode *firstEdge;
    }VertexNode, HeadCellArray[MAX_VERTEX_NUM];
    
    typedef struct         // 图结构
    {
        int numVertex, numEdge;
        HeadCellArray headCellArray;
    }Graph;
    
    
    int * MakeIndegree(Graph G)
    {
        int i;
        int *indegree;
        EdgeNode *p;
    
        indegree=(int*)malloc(sizeof(int)*G.numVertex);
    
        for (i=0;i<G.numVertex;i++)
        {
            p = G.headCellArray[i].firstEdge;
            while(p)
            {
                (indegree[p->adjvertex])++;
                p = p->next;
            }
        }
    
        return indegree;
    }
    
    int FindNewVertexOfIndegreeZero(int *indegree, int n)
    {
        int i, temp, NotAVertex=-1, IndegreeZero;
        for (i=0;i<n;i++)
        {
            if (indegree[i] == 0)
            {
                indegree[i] = 100;             // 100表示该顶点已被分配
                IndegreeZero = i;
                break;
            }
        }
    
        if (IndegreeZero != -1)
            return IndegreeZero;
        return NotAVertex;
    }
    
    void Topsort(Graph G)
    {
        int counter;
        int v, w;
        int *indegree;
        EdgeNode *p;
        indegree = MakeIndegree(G);
    
        for (counter=0;counter<G.numVertex;counter++)
        {
            v = FindNewVertexOfIndegreeZero(indegree, G.numVertex);
            if (v == -1)
            {
                printf("%s", "Graph has cycle.");
                break;
                return;
            }
    
            TopNum[v] = counter;
            p = G.headCellArray[v].firstEdge;
            while(p)
            {
                w=p->adjvertex;
                indegree[w]--;
                p = p->next;
            }
        }
        
        return;
    }
    
    Graph InitGraph()
    {
        Graph G;
        EdgeNode *p;
        int i, u, v;
    
        printf("请输入节点数和边数:
    ");
        scanf("%d%d", &G.numVertex, &G.numEdge);
    
        for (i=0;i<G.numVertex;i++)
        {
            G.headCellArray[i] = *(VertexNode*)malloc(sizeof(VertexNode));
            G.headCellArray[i].vertex=i;
            G.headCellArray[i].firstEdge=NULL;
        }
    
        for (i=0;i<G.numEdge;i++) 
        {
            printf("请输入边(u, v),即u->v
    ");
            scanf("%d%d", &u, &v);
    
            p=(EdgeNode*)malloc(sizeof(EdgeNode));
            p->adjvertex=v;
            p->next=G.headCellArray[u].firstEdge;
            G.headCellArray[u].firstEdge=p;
        }
    
        return G;
    }
    
    void PrintGraph(Graph G)
    {
        int i;
        EdgeNode *p;
    
        for(i=0;i<G.numVertex;i++)
        {
            printf("顶点%d", G.headCellArray[i].vertex);
            p=G.headCellArray[i].firstEdge;
            while(p)
            {
                printf("->%3d", p->adjvertex);
                p=p->next;
            }
            printf("
    ");
        }
    }
    
    void main()
    {
        int i, *p, temp;
        Graph G;
    
        G=InitGraph();
        PrintGraph(G);
    
    /*
        p=MakeIndegree(G);
        for(i=0;i<7;i++)
            printf("%4d", p[i]);
    */
    /*
        temp=FindNewVertexOfIndegreeZero(p, 7);
        printf("%d
    ", temp);
    */
        Topsort(G);    
        for(i=0;i<MAX_VERTEX_NUM;i++)
            printf("%4d
    ", TopNum[i]);
    
    }

    这里只对我编程时遇到的几个问题进行简单的说明:

    1.malloc函数的使用,很久没有用C了,所以开始的时候是这样用的:

    G.headCellArray[i] = (VertexNode)malloc(sizeof(VertexNode));

         产生的错误困扰了我半天。

    2.另一个错误是在编写函数的时候没有注意到前向引用的问题,MakeIndegree(Graph G);等函数放在了Topsort(Graph G);后面导致错误。

    3.最后一个问题是FindNewVertexOfIndegreeZero(int *indegree, int n);中忘记break了,导致输出序列错误。

    注:TopNum输出的序列不是最后的拓扑序列,它是key,和value反的,value代表的是下面下标应该在的位置。

  • 相关阅读:
    走读OpenSSL代码从一张奇怪的证书说起(二)
    从数学到密码学(十八)
    从数学到密码学(十七)
    走读OpenSSL代码从一张奇怪的证书说起(一)
    从数学到密码学(十六)
    从数学到密码学(十五)
    从数学到密码学(十三)
    从数学到密码学(十九)
    从数学到密码学(十四)
    关于Terracotta DSO 安装
  • 原文地址:https://www.cnblogs.com/selfimprovement/p/5991290.html
Copyright © 2011-2022 走看看