實驗四(建圖,無向圖+鄰接矩陣(BFS,DFS(遞迴+非遞迴)),有向圖+鄰接表(BFS,DFS(遞迴+非遞迴)),拓撲排序)
阿新 • • 發佈:2018-12-19
//Sinhaeng Hhjian #include<bits/stdc++.h> using namespace std; const int N=100; const int MAX=1000; int book[N], cnt; struct node{ char x[N]; int mp[N][N]; int v, e; }; struct anode{ int ad, wei; anode *next; }; struct vnode{ char x; anode *fir; int ind; }; struct graph{ vnode ver[N]; int v, e; }; //佇列 struct Queue{ int *base; int f, r; }; void InitQueue(Queue &q){ q.base = (int *)malloc(sizeof(int) * MAX); q.f = q.r = 0; } void InQueue(Queue &q, int bt){ q.base[q.r++] = bt; } int IsEmpty(Queue q){ return q.f == q.r? 1:0; } void OutQueue(Queue &q, int &bt){ if(IsEmpty(q)) return ; bt = q.base[q.f++]; } //棧 struct Stack{ int *base; int top; }; void Push(Stack &s, int bt){ s.base[++s.top] = bt; } int GetTop(Stack s, int &bt){ if(!s.top) return 0; bt = s.base[s.top]; return 1; } int IsSEmpty(Stack s){ return s.top==0? 1 : 0; } void InitStack(Stack &s){ s.base = (int *)malloc(MAX*(sizeof(int))); s.top=0; } void Pop(Stack &s){ if(IsSEmpty(s)) return ; s.top--; } //建圖 int lx(node &G, char x){ for(int i=0;i<G.v;i++) if(G.x[i]==x) return i; return -1; } int ly(graph &GG, char x){ for(int i=0;i<GG.v;i++) if(GG.ver[i].x==x) return i; return -1; } void wuxiang(node &G){ char u, v; printf("建立無向圖的鄰接矩陣:\n請輸入頂點數和邊數:"); scanf("%d %d", &G.v, &G.e); printf("請輸入頂點資訊(頂點間不要有空格):\n"); getchar(); for(int i=0;i<G.v;i++) scanf("%c", &G.x[i]); getchar(); for(int i=0;i<G.v;i++) for(int j=0;j<G.v;j++) G.mp[i][j]=0; printf("請輸入無向圖的邊(兩頂點間加空格,並且每輸入一條邊用回車來間隔開另一條邊):\n"); for(int k=0;k<G.e;k++){ scanf("%c %c", &u, &v); getchar(); int i=lx(G, u); if(i==-1){ printf("ERROR\n"); return ; } int j=lx(G, v); if(j==-1){ printf("ERROR\n"); return ; } G.mp[i][j]=G.mp[j][i]=1; } printf("鄰接矩陣儲存無向圖結果:\n "); for(int i=0;i<G.v;i++) printf("%3c", G.x[i]); printf("\n"); for(int i=0;i<G.v;i++){ printf("%3c", G.x[i]); for(int j=0;j<G.v;j++) printf("%3d", G.mp[i][j]); printf("\n"); } } void youxiang(graph &GG){ char u, v; printf("建立有向圖的鄰接表:\n請輸入頂點數和邊數:"); scanf("%d %d", &GG.v, &GG.e); printf("請輸入頂點資訊(頂點間不要有空格):\n"); getchar(); for(int i=0;i<GG.v;i++){ scanf("%c", &GG.ver[i].x); GG.ver[i].fir=NULL; } getchar(); printf("請輸入有向圖的邊(兩頂點間加空格,並且每輸入一條邊用回車來間隔開另一條邊):\n"); for(int i=0;i<GG.v;i++) GG.ver[i].ind=0; for(int k=0;k<GG.e;k++){ scanf("%c %c", &u, &v); getchar(); int i=ly(GG, u); if(i==-1){ printf("ERROR\n"); return ; } int j=ly(GG, v); if(j==-1){ printf("ERROR\n"); return ; } anode *s=(anode *)malloc(sizeof(anode)); s->ad=j;s->next=NULL; if(!GG.ver[i].fir) GG.ver[i].fir=s; else{ anode *p=GG.ver[i].fir; while(p->next) p=p->next; p->next=s; } } printf("鄰接表儲存有向圖結果:\n"); for(int i=0;i<GG.v;i++){ printf("%3c", GG.ver[i].x); anode *p=GG.ver[i].fir; while(p){ printf(" ->%3c", GG.ver[p->ad].x); p=p->next; } printf("\n"); } } //無向圖的遍歷 void dfs1(node &G, int x){ book[x]=1; printf("%3c", G.x[x]); for(int i=0;i<G.v;i++) if(G.mp[x][i] && !book[i]) dfs1(G, i); } void wuxiangdfs(node &G){ printf("對無向圖的深度優先遍歷(遞迴演算法):\n"); for(int i=0;i<G.v;i++){ if(!book[i]){ dfs1(G, i); } } printf("\n"); } void bfs1(node &G, int x){ Queue q; InitQueue(q); InQueue(q, x); book[x]=1; while(!IsEmpty(q)){ int bt; OutQueue(q, bt); printf("%3c", G.x[bt]); for(int i=0;i<G.v;i++) if(G.mp[bt][i] && !book[i]){ InQueue(q, i); book[i]=1; } } } void wuxiangbfs(node &G){ printf("對無向圖的廣度優先遍歷:\n"); for(int i=0;i<N;i++) book[i]=0; for(int i=0;i<G.v;i++) if(!book[i]) bfs1(G, i); printf("\n"); } void dfs11(node &G, int x){ int i, j, k; Stack S; InitStack(S); Push(S, x); printf("%3c", G.x[x]); book[x]=1; while(!IsSEmpty(S)){ GetTop(S, i); for(j=0;j<G.v;j++){ if(G.mp[i][j] && !book[j]){ Push(S, j); printf("%3c", G.x[j]); book[j]=1; i=j; j=0; } } if(!IsSEmpty(S)) Pop(S); } } void wuxiangfdfs(node &G){ printf("對無向圖的深度優先遍歷(非遞迴演算法):\n"); for(int i=0;i<G.v;i++) book[i]=0; for(int i=0;i<G.v;i++) if(!book[i]) dfs11(G, i); printf("\n"); } //有向圖的遍歷 void dfs2(graph &GG, int x){ anode *p; book[x]=1; p=GG.ver[x].fir; printf("%3c", GG.ver[x].x); while(p){ if(!book[p->ad]) dfs2(GG, p->ad); p=p->next; } } void youxiangdfs(graph &GG){ printf("對有向圖的深度優先遍歷(遞迴演算法):\n"); for(int i=0;i<N;i++) book[i]=0; for(int i=0;i<GG.v;i++) if(!book[i]) dfs2(GG, i); printf("\n"); } void bfs2(graph &GG, int x){ Queue q; InitQueue(q); InQueue(q, x); book[x]=1; while(!IsEmpty(q)){ OutQueue(q, x); printf("%3c", GG.ver[x].x); anode *p=GG.ver[x].fir; while(p){ if(!book[p->ad]){ book[p->ad]=1; InQueue(q, p->ad); } p=p->next; } } } void youxiangbfs(graph &GG){ printf("對有向圖的廣度優先遍歷:\n"); for(int i=0;i<N;i++) book[i]=0; for(int i=0;i<GG.v;i++) if(!book[i]) bfs2(GG, i); printf("\n"); } void dfs22(graph &GG, int x){ Stack s; InitStack(s); anode *p; book[x]=1; Push(s, x); printf("%3c", GG.ver[x].x); while(!IsSEmpty(s)){ p = GG.ver[s.base[s.top]].fir; while(p){ if(!book[p->ad]){ book[p->ad]=1; printf("%3c", GG.ver[p->ad].x); Push(s, p->ad); p=GG.ver[p->ad].fir; } else p=p->next; } if(!p) Pop(s); } } void youxiangfdfs(graph &GG){ printf("對有向圖的深度優先遍歷(非遞迴演算法):\n"); for(int i=0;i<GG.v;i++) book[i]=0; for(int i=0;i<GG.v;i++) if(!book[i]) dfs22(GG, i); printf("\n"); } void tuopu(graph &GG){ printf("對有向圖的拓撲排序為:\n"); Stack s;cnt=0; InitStack(s); int a[N], c=0; for(int i=0;i<GG.v;i++) if(GG.ver[i].ind==0) Push(s, i); while(!IsSEmpty(s)){ int xx=s.base[s.top]; a[c++]=xx; Pop(s); cnt++; for(anode *p=GG.ver[xx].fir;p;p=p->next){ int k=p->ad; GG.ver[k].ind--; if(!GG.ver[k].ind) Push(s, k); } } if(cnt<GG.v) printf("該圖有迴路\n"); else{ for(int i=0;i<c;i++) printf("%3c", GG.ver[i].x); printf("\n"); } } int main() { node G; wuxiang(G); wuxiangdfs(G); wuxiangbfs(G); wuxiangfdfs(G); graph GG; youxiang(GG); youxiangdfs(GG); youxiangbfs(GG); youxiangfdfs(GG); tuopu(GG); return 0; }