拓撲排序(基於鄰接表實現),拓撲排序鄰接表
#include <iostream>#include <stack> using namespace std;#define MAX 100typedef char VertexType; typedef struct ArcNode { int adjvex; //鄰接點域,儲存該弧指向頂點的下標 (終點) struct ArcNode *next;//指向下一條弧的指標 int weight;//權重 }ArcNode;//邊結構 typedef struct VertexNode {VertexType data;//資料域 ArcNode *firstArc;//指向第一條依附該頂點的弧的指標 }VertexNode,AdjVerList[MAX];typedef struct {AdjVerList vertices;//頂點集int vexnum,arcnum; //圖的頂點數和弧數}ALGraph;//圖結構int indegree[MAX];//每個頂點對應的入度數組 void CreateALGraph(ALGraph *G);void Display(ALGraph *G);int TopoSort(ALGraph *G);//a b c d e f g h i /*a c 0a h 0b c 0b d 0b e 0c d 0d f 0d g 0e f 0h i 0i g 0*/int main(){ALGraph G;CreateALGraph(&G);//Display(&G);TopoSort(&G);return 0;}//求頂點位置函數int LocateVex(ALGraph *G,VertexType v){ int i; for(i=0;i<G->vexnum;i++) { if(G->vertices[i].data == v) return i; } return -1;}//有向非循環圖 void CreateALGraph(ALGraph *G){ VertexType v1,v2; int w; ArcNode *Arc; cout<<"請輸入頂點數和邊數:"; cin>>G->vexnum>>G->arcnum; cout<<"請輸入各頂點的資料:"; for(int i=0;i<G->vexnum;i++){ cin>>G->vertices[i].data; G->vertices[i].firstArc = NULL; //頂點的邊表設為空白 } cout<<"請依次輸入"<<G->arcnum<<"組邊對應的兩個頂點以及權值,以空格分割:"<<endl; for(int k=0;k<G->arcnum;k++) {cin>>v1>>v2>>w; int i = LocateVex(G,v1); int j = LocateVex(G,v2); Arc = new ArcNode;//建立邊 Arc->adjvex = j; Arc->weight = w; Arc->next = G->vertices[i].firstArc; G->vertices[i].firstArc = Arc; }}void Display(ALGraph *G){ ArcNode *p; cout<<"編號, 頂點, 相鄰邊的頂點\n"; for(int i=0;i<G->vexnum;i++) { cout<<i<<"\t"<<G->vertices[i].data; for(p=G->vertices[i].firstArc;p!=NULL;p=p->next) cout<<"\t"<<p->adjvex; cout<<endl; }}//求各頂點的入度(遍曆整個鄰接表)void FindIndegree(ALGraph *G){int i;ArcNode *p; //初始化每個頂點的入度為0for(i=0;i<G->vexnum;i++) indegree[i] = 0; for(i=0;i<G->vexnum;i++) { p = G->vertices[i].firstArc; while(p) { //將每一個臨接到的點(終點)自增 indegree[p->adjvex]++; p = p->next; } //cout<<i<<"元素的入度為:"<<indegree[i]<<endl; } } //傳回值的失敗與否代表該有向圖是否存在迴路//拓撲排序 int TopoSort(ALGraph *G){cout<<"該有向圖的一種拓撲排序結果為:"<<endl; stack<int> s;//設定輔助棧,避免重複資料偵測入度為0的頂點ArcNode *p;int i,k;FindIndegree(G);for(i=0;i<G->vexnum;i++){//將入度為0的頂點入棧if(indegree[i]==0)s.push(i); }int count = 0;while(!s.empty()){i = s.top();s.pop();cout<<G->vertices[i].data<<" "; //將棧頂出棧並列印count++;//統計已輸出的頂點數 p = G->vertices[i].firstArc;while(p!=NULL){k = p->adjvex;indegree[k]--;//i號頂點已出棧,所以將i號頂點的每個鄰接點的入度自減 if(indegree[k]==0)s.push(k);//如果入度減為0,則入棧p = p->next; }}if(count<G->vexnum)return -1;//存在迴路 elsereturn 0;}