無向圖的鄰接矩陣,深度優先遍歷廣度優先遍歷的遞迴與非遞迴演算法
阿新 • • 發佈:2019-02-13
/*(1)輸入一組頂點,建立無向圖的鄰接矩陣。 進行DFS(深度優先遍歷)和BFS(廣度優先遍歷)。 寫出深度優先遍歷的遞迴和非遞迴演算法。*/ #include<stdio.h> #define max 40 //最大頂點個數 #define M 10000 //無窮 #include<stdlib.h> typedef struct ArcCell{ int adj; //1/0表示是否有邊。網中表示權值 }ArcCell,AdjMatrix[max][max]; typedef struct{ char vexs[max]; //頂點表 AdjMatrix arcs; //矩陣表 int vexnum,arcnum; //頂點數和邊數 }MGraph; typedef struct QNode{ int data; struct QNode *next; }QNode,*QueuePtr; typedef struct{ QueuePtr front; QueuePtr rear; }LinkQueue; int InitQueue(LinkQueue &Q){ Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode)); if(!Q.front) exit(0); Q.front->next=NULL; return 1; } int QueueEmpty(LinkQueue Q){ if(Q.front==Q.rear) return 1; else return 0; } int EnQueue(LinkQueue &Q,int e){ QueuePtr p; p=(QueuePtr)malloc(sizeof(QNode)); if(!p) exit(0); p->data=e; p->next=NULL; Q.rear->next=p; Q.rear=p; return 1; } int DeQueue(LinkQueue &Q,int &e){ QueuePtr p; if(Q.front==Q.rear) return 0; p=Q.front->next; e=p->data; Q.front->next=p->next; if(Q.rear==p) Q.rear=Q.front; free(p); return 1; } int Locatevex(MGraph G,char v){ int i; for(i=0;i<G.vexnum;i++){ if(G.vexs[i]==v) return i; } } void GreatGraph(MGraph &G){ //建立無向圖G的鄰接矩陣 int i,j,k; char v1,v2; printf("輸入頂點數和邊數:"); scanf("%d%d",&G.vexnum,&G.arcnum); getchar(); printf("輸入頂點的資訊:\n"); for(i=0;i<G.vexnum;i++){ scanf("%c",&G.vexs[i]); } //初始化矩陣 for(i=0;i<G.vexnum;i++){ for(j=0;j<G.vexnum;j++){ G.arcs[i][j].adj=0; } } getchar(); printf("輸入邊:\n"); for(k=0;k<G.arcnum;k++){ scanf("%c%c",&v1,&v2); getchar(); i=Locatevex(G,v1); j=Locatevex(G,v2); G.arcs[i][j].adj=G.arcs[j][i].adj=1; } } int FirstAdjvex(MGraph G,int v){ //查詢第一個鄰接點 int j; for(j=0;j<G.vexnum;j++){ if(G.arcs[v][j].adj==1) return j; else return -1; } } int NextAdjvex(MGraph G,int v,int w){ //查詢下一個鄰接點 int j; for(j=w+1;j<G.vexnum;j++){ if(G.arcs[v][j].adj==1) return j; else return -1; } } void PrintGraph(MGraph G){ //按鄰接矩陣方式輸出無向圖 int i,j; for(i=0;i<G.vexnum;i++){ printf("%10c",G.vexs[i]); for(j=0;j<G.vexnum;j++) printf("%4d",G.arcs[i][j].adj); printf("\n"); } } int visited1[max]; void Dfs(MGraph G,int v){ int j; visited1[v]=1; printf("%c",G.vexs[v]); for(j=0;j<G.vexnum;j++){ if(!visited1[j]&&G.arcs[v][j].adj!=0) Dfs(G,j); } } void DfsTraverse(MGraph G){ //深度優先遍歷遞迴演算法 int v; for(v=0;v<G.vexnum;v++){ visited1[v]=0; } for(v=0;v<G.vexnum;v++){ if(!visited1[v]) Dfs(G,v); } } void DfsTraverse2(MGraph G){ //深度優先遍歷非遞迴演算法 int visited2[max]; int v,u,w; LinkQueue Q; for(v=0;v<G.vexnum;v++) visited2[v]=0; InitQueue(Q); for(v=0;v<G.vexnum;v++) if(!visited2[v]){ visited2[v]=1; printf("%c",G.vexs[v]); EnQueue(Q,v); while(!QueueEmpty(Q)){ DeQueue(Q,u); for(w=FirstAdjvex(G,u);w>=0;w=NextAdjvex(G,u,w)) if(!visited2[w]){ visited2[w]=1; printf("%c",G.vexs[w]); EnQueue(Q,w); } } } } void BfsTraverse(MGraph G){ //廣度優先遍歷 int visited3[max]; int v,u,w; LinkQueue Q; for(v=0;v<G.vexnum;v++) visited3[v]=0; InitQueue(Q); for(v=0;v<G.vexnum;v++) if(!visited3[v]){ visited3[v]=1; printf("%c",G.vexs[v]); EnQueue(Q,v); while(!QueueEmpty(Q)){ DeQueue(Q,u); for(w=0;w<G.vexnum;w++) if(!visited3[w]&&G.arcs[u][w].adj!=0){ visited3[w]=1; printf("%c",G.vexs[w]); EnQueue(Q,w); } } } } int main(){ MGraph G; GreatGraph(G); PrintGraph(G); printf("\nDfs(遞迴):"); DfsTraverse(G); printf("\nDfs(非遞迴):"); DfsTraverse2(G); printf("\nBfs:"); BfsTraverse(G); return 0; }