拓撲排序(一)之 C語言詳解
阿新 • • 發佈:2018-12-30
/* * 拓撲排序 * * 引數說明: * G -- 鄰接表表示的有向圖 * 返回值: * -1 -- 失敗(由於記憶體不足等原因導致) * 0 -- 成功排序,並輸入結果 * 1 -- 失敗(該有向圖是有環的) */ int topological_sort(LGraph G) { int i,j; int index = 0; int head = 0; // 輔助佇列的頭 int rear = 0; // 輔助佇列的尾 int *queue; // 輔組佇列 int *ins; // 入度陣列 char *tops; // 拓撲排序結果陣列,記錄每個節點的排序後的序號。 int num = G.vexnum; ENode *node; ins = (int *)malloc(num*sizeof(int)); // 入度陣列 tops = (char *)malloc(num*sizeof(char));// 拓撲排序結果陣列 queue = (int *)malloc(num*sizeof(int)); // 輔助佇列 assert(ins!=NULL && tops!=NULL && queue!=NULL); memset(ins, 0, num*sizeof(int)); memset(tops, 0, num*sizeof(char)); memset(queue, 0, num*sizeof(int)); // 統計每個頂點的入度數 for(i = 0; i < num; i++) { node = G.vexs[i].first_edge; while (node != NULL) { ins[node->ivex]++; node = node->next_edge; } } // 將所有入度為0的頂點入佇列 for(i = 0; i < num; i ++) if(ins[i] == 0) queue[rear++] = i; // 入佇列 while (head != rear) // 佇列非空 { j = queue[head++]; // 出佇列。j是頂點的序號 tops[index++] = G.vexs[j].data; // 將該頂點新增到tops中,tops是排序結果 node = G.vexs[j].first_edge; // 獲取以該頂點為起點的出邊佇列 // 將與"node"關聯的節點的入度減1; // 若減1之後,該節點的入度為0;則將該節點新增到佇列中。 while(node != NULL) { // 將節點(序號為node->ivex)的入度減1。 ins[node->ivex]--; // 若節點的入度為0,則將其"入佇列" if( ins[node->ivex] == 0) queue[rear++] = node->ivex; // 入佇列 node = node->next_edge; } } if(index != G.vexnum) { printf("Graph has a cycle\n"); free(queue); free(ins); free(tops); return 1; } // 列印拓撲排序結果 printf("== TopSort: "); for(i = 0; i < num; i ++) printf("%c ", tops[i]); printf("\n"); free(queue); free(ins); free(tops); return 0; }