關於鄰接表的拓撲排序
阿新 • • 發佈:2019-02-17
演算法思想如下:
利用鄰接表儲存圖,先設一個輔助陣列indegree[]來計算所有節點的入度;首先把入度為零的節點入棧,當棧不為空時,把棧中的元素出棧,然後刪除輸出元素為弧尾的所有弧,並判斷相應節點的入度是否為零,為零,則壓入棧中。重複執行,直到棧空。
#include <stdio.h> #include <stdlib.h> #define MAX 30 int indegree[MAX];//用來儲存所有節點的入度之和 typedef struct ArcNode{ struct ArcNode *nextarc; int adjvex; }ArcNode; typedef struct{ ArcNode *firstarc; char data; }VNode,Vertice[MAX]; typedef struct{ int vexnum,arcnum; Vertice vex; }ALGraph; typedef struct{ int top; int *base; int stacksize; }SqStack; int LocateVex(ALGraph G, char v){ for(int i = 0; i < G.vexnum; i ++){ if(v == G.vex[i].data) return i; } return -1; } void CreateALGraph(ALGraph &G){ int i,j,k; char v1,v2; ArcNode *p,*s; printf("輸入節點和邊的數目:\n"); scanf("%d%d",&G.vexnum,&G.arcnum); printf("輸入結點:\n"); getchar(); for(i = 0; i < G.vexnum; i ++){ scanf("%c",&G.vex[i].data); G.vex[i].firstarc = NULL; } printf("輸入各條邊:\n"); for(i = 0; i < G.arcnum; i ++){ getchar(); scanf("%c%c",&v1,&v2); j = LocateVex(G,v1); k = LocateVex(G,v2); s = (ArcNode *)malloc(sizeof(ArcNode)); s->adjvex = k; s->nextarc = NULL; if(!G.vex[j].firstarc){ G.vex[j].firstarc = s; } else{ p = G.vex[j].firstarc; while(p->nextarc) p = p->nextarc; p->nextarc = s; } } } void FindInputDgeree(ALGraph G){//計算所有節點的入度 ArcNode *p; int i; for(i = 0; i < G.vexnum; i ++) indegree[i] = 0; for(i = 0; i < G.vexnum; i ++){ p = G.vex[i].firstarc; while(p){ indegree[p->adjvex] ++; p = p->nextarc; } } } void InitStack(SqStack &S){ S.base = (int *)malloc(sizeof(int) * MAX); if(!S.base) return ; S.top = 0; S.stacksize = MAX; } void Push(SqStack &S, int i){ if(S.top >= S.stacksize){ S.base = (int *)realloc(S.base,(S.top + MAX) * sizeof(int)); if(!S.base) return ; S.stacksize += MAX; } S.base[S.top ++] = i; } int StackEmpty(SqStack S){ if(!S.top ) return 1; return 0; } void Pop(SqStack &S, int &i){ if(!S.top) return; i = S.base[-- S.top]; } void TopologicalSort(ALGraph G){ FindInputDgeree(G); int count = 0,i; SqStack S; ArcNode *p; InitStack(S); for(i = 0; i < G.vexnum; i ++) if(!indegree[i])//把入度為零的節點入棧 Push(S,i); printf("拓撲序列如下:\n"); while(!StackEmpty(S)){ Pop(S,i); printf("%c\n",G.vex[i].data); count ++; p = G.vex[i].firstarc; while(p){ if(!(-- indegree[p->adjvex]))//判斷去掉一條邊後節點的入度是否為零 Push(S,p->adjvex); p = p->nextarc; } } if(count < G.vexnum) printf("該圖為有向有環圖\n"); } int main(){ ALGraph G; CreateALGraph(G);//建立圖 TopologicalSort(G);//進行拓撲排序 return 0; }