6-13 Topological Sort(25 分)

Write a program to find the topological order in a digraph.

Format of functions:

bool TopSort( LGraph Graph, Vertex TopOrder[] );

where LGraph is defined as the following:

typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
    Vertex AdjV;
    PtrToAdjVNode Next;
};

typedef struct Vnode{
    PtrToAdjVNode FirstEdge;
} AdjList[MaxVertexNum];

typedef struct GNode *PtrToGNode;
struct GNode{  
    int Nv;
    int Ne;
    AdjList G;
};
typedef PtrToGNode LGraph;

The topological order is supposed to be stored in TopOrder[] where TopOrder[i] is the i-th vertex in the resulting sequence. The topological sort cannot be successful if there is a cycle in the graph -- in that case TopSort must return false; otherwise return true.

Notice that the topological order might not be unique, but the judge's input guarantees the uniqueness of the result.

Sample program of judge:

#include 
#include 

typedef enum {false, true} bool;
#define MaxVertexNum 10  /* maximum number of vertices */
typedef int Vertex;      /* vertices are numbered from 0 to MaxVertexNum-1 */

typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
    Vertex AdjV;
    PtrToAdjVNode Next;
};

typedef struct Vnode{
    PtrToAdjVNode FirstEdge;
} AdjList[MaxVertexNum];

typedef struct GNode *PtrToGNode;
struct GNode{  
    int Nv;
    int Ne;
    AdjList G;
};
typedef PtrToGNode LGraph;

LGraph ReadG(); /* details omitted */

bool TopSort( LGraph Graph, Vertex TopOrder[] );

int main()
{
    int i;
    Vertex TopOrder[MaxVertexNum];
    LGraph G = ReadG();

    if ( TopSort(G, TopOrder)==true )
        for ( i=0; iNv; i++ )
            printf("%d ", TopOrder[i]);
    else
        printf("ERROR");
    printf("\n");

    return 0;
}

/* Your function will be put here */

Sample Input 1 (for the graph shown in the figure):

5 7
1 0
4 3
2 1
2 0
3 2
4 1
4 2

Sample Output 1:

4 3 2 1 0

Sample Input 2 (for the graph shown in the figure):

5 8
0 3
1 0
4 3
2 1
2 0
3 2
4 1
4 2

Sample Output 2:

ERROR

#include 
#include 

typedef enum {false, true} bool;
#define MaxVertexNum 10  /* maximum number of vertices */
typedef int Vertex;      /* vertices are numbered from 0 to MaxVertexNum-1 */

typedef struct AdjVNode *PtrToAdjVNode; //  指向邻接表结点的指针
struct AdjVNode{    //  邻接表结点   //边表结点
    Vertex AdjV;    //  结点序号, 用于标识
    PtrToAdjVNode Next; //  next 指针
};

typedef struct Vnode{   //  顶点结点
    PtrToAdjVNode FirstEdge; // 指向该结点的第一个 邻接表结点 的指针
} AdjList[MaxVertexNum];    //  数组

typedef struct GNode *PtrToGNode;   //  指向整张图的指针
struct GNode{   //  图
    int Nv; //  整个图的顶点个数
    int Ne; //  整个图的边个数
    AdjList G;  //  存放顶点的数组
};
typedef PtrToGNode LGraph;  //  指向整张图的 二级 指针

LGraph ReadG(); /* details omitted */

bool TopSort( LGraph Graph, Vertex TopOrder[] );    //  返回值表示排序成功与否

int main()
{
    int i;
    Vertex TopOrder[MaxVertexNum];
    LGraph G = ReadG();

    if ( TopSort(G, TopOrder)==true )
        for ( i=0; iNv; i++ )
            printf("%d ", TopOrder[i]);
    else
        printf("ERROR");
    printf("\n");

    return 0;
}

/* Your function will be put here */


void FindIndegree(LGraph Graph, int indegree[]) //  入度
{
    for(int i = 0; i < Graph->Nv; ++i)  //
        indegree[i] = 0;
    PtrToAdjVNode current;
    for(int i = 0; i < Graph->Nv; ++i)  //
    {
        current = Graph->G[i].FirstEdge;    //
        while(current != NULL)
        {
            indegree[current->AdjV] = indegree[current->AdjV] + 1;
            current = current->Next;
        }
    }
}
bool TopSort( LGraph Graph, Vertex TopOrder[] ) //  拓扑排序
{
    int indegree[Graph->Nv];
    FindIndegree(Graph, indegree);
    /*int visited[Graph->Nv];
    for(int i = 0; i < Graph->Nv; ++i)
        visited[i] = 0;*/
    int Q[Graph->Nv];
    int first = 0, rear = 0;
    for(int i = 0; i < Graph->Nv; ++i)  //  所有入度为零的(结点)入队
        if(indegree[i] == 0){
            Q[rear++] = i;
            //visited[i] = 1;
        }
    int cnt = 0;
    int Qhead;
    PtrToAdjVNode current;
    //int pre_rear;
    while(first < rear) //  当队列非空时
    {
        Qhead = Q[first++];
        TopOrder[cnt++] = Qhead;
        current = Graph->G[Qhead].FirstEdge;
        //pre_rear = rear;
        while(current != NULL)
        {   //  当前 出队结点(入度零) 的后继结点的入度均减一
            //  并将入度减至零的结点入队
            indegree[current->AdjV] = indegree[current->AdjV] - 1;
            if(indegree[current->AdjV] == 0)
                Q[rear++] = current->AdjV;
            current = current->Next;
        }
         //if(pre_rear == rear) return false;
    }
    if(cnt == Graph->Nv) return true;
    else return false;
}

你可能感兴趣的:(PTA-Data,Structures,and,Algori,图论)