編寫程序以在有向圖中找到拓撲順序。node
bool TopSort( LGraph Graph, Vertex TopOrder[] );
其中LGraph
定義以下:spa
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
。code
請注意,拓撲順序可能不是惟一的,可是判斷的輸入保證告終果的惟一性。blog
#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 */
5 7 1 0 4 3 2 1 2 0 3 2 4 1 4 2
4 3 2 1 0
5 8 0 3 1 0 4 3 2 1 2 0 3 2 4 1 4 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; }