6-1 Topological Sort (25 分)
編寫程序以在有向圖中找到拓撲順序。
功能格式:
bool TopSort( LGraph Graph, Vertex TopOrder[] );
其中LGraph定義如下:
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;
拓撲順序應該被存儲在TopOrder[]其中,TopOrder[i]是i將得到的序列中的第一個頂點。如果圖中有一個循環,則拓撲排序不能成功 - 在這種情況下TopSort必須返回false; 否則返回true。
請注意,拓撲順序可能不是唯一的,但是判斷的輸入保證了結果的唯一性。
法官示例程序:
#include <stdio.h>
#include <stdlib.h>
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; i<G->Nv; i++ )
printf("%d ", TopOrder[i]);
else
printf("ERROR");
printf("\n");
return 0;
}
/* Your function will be put here */
樣本輸入1(對於圖中所示的圖表):

5 7 1 0 4 3 2 1 2 0 3 2 4 1 4 2
樣本輸出1:
4 3 2 1 0
樣本輸入2(對於圖中所示的圖表):

5 8 0 3 1 0 4 3 2 1 2 0 3 2 4 1 4 2
樣本輸出2:
ERROR
bool TopSort( LGraph Graph, Vertex TopOrder[] )
{
int Indegree[Graph->Nv];//建立入度表
int Queue[Graph->Nv];//建立隊列存儲入隊為0的節點
int pre=0, tail=0;//隊首和隊尾
PtrToAdjVNode p;
for(int i=0; i<Graph->Nv; i++)
Indegree[i] = 0;//初始化入度表為0
for(int i=0; i<Graph->Nv; i++){//構造入度表
for(p=Graph->G[i].FirstEdge; p!=NULL; p=p->Next)
Indegree[p->AdjV]++;
}
for(int i=0; i<Graph->Nv; i++){//將入度為0的節點入隊
if(!Indegree[i])
Queue[tail++] = i;
}
int num = 0;//記錄入隊的數目
while(pre < tail){
int pos = Queue[pre];
TopOrder[num++] = Queue[pre++];
for(p=Graph->G[pos].FirstEdge; p!=NULL; p=p->Next){
int index = p->AdjV;
--Indegree[index];//將出隊的節點,即刪除的節點的鄰接節點入隊減1
if(!Indegree[index])//若更新入度后入度為0則入隊
Queue[tail++] = index;
}
}
if(num == Graph->Nv)
return true;
else
return false;
}
