1 /** 2 知識點:(有向圖) 3 強連通圖的鄰接矩陣存儲圖; 4 強連通圖的深度優先遍歷(遞歸方式實現) 5 強連通圖的廣度優先遍歷(遞歸+非遞歸實現) 6 */ 7 #include <stdio.h> 8 #include <string.h> 9 #define N 5 10 #define ARC 100 11 int visit[ARC],visitQ[ARC]; 12 typedef struct { 13 char vex[ARC][N];///頂點 14 int arc[ARC][ARC]; 15 int numv,nume;///頂點,邊的個數 16 }Graph; 17 int getIndex(Graph& G,char s[]){ 18 for(int i = 0; i < G.numv; i++){ 19 if(strcmp(s,G.vex[i]) == 0) 20 return i; 21 } 22 return -1; 23 } 24 void create(Graph& G){ 25 printf("請分別輸入頂點和邊的個數:\n"); 26 scanf("%d%d",&G.numv,&G.nume); 27 printf("輸入圖的頂點信息:\n"); 28 for(int i = 0; i < G.numv; i++) 29 scanf("%s",G.vex[i]); 30 printf("請輸入邊的信息:\n"); 31 ///初始化數組G.arc 32 for(int i = 0; i < G.numv; i++) 33 for(int j = 0; j < G.numv; j++) 34 G.arc[i][j] = 0; 35 char s[N],e[N]; 36 int i = 0,u,v; 37 while(i < G.nume){ 38 scanf("%s%s",s,e); 39 u = getIndex(G,s); 40 v = getIndex(G,e); 41 ///假設輸入的起始和終止頂點都存在 42 G.arc[u][v] = 1; 43 i++; 44 } 45 } 46 ///輸出矩陣 47 void output(Graph G){ 48 printf(" "); 49 for(int i = 0; i < G.numv; i++) 50 printf("%4s",G.vex[i]); 51 printf("\n"); 52 for(int i = 0; i < G.numv; i++){ 53 for(int j = -1; j < G.numv; j++){ 54 if(j == -1) 55 printf("%4s",G.vex[i]); 56 else{ 57 printf("%4d",G.arc[i][j]); 58 } 59 } 60 printf("\n"); 61 } 62 } 63 64 ///查找圖G中位序為s的第一個鄰接點 65 int firstVex(Graph G,int s){ 66 for(int i = 0; i < G.numv; i++){ 67 if(G.arc[s][i] == 1) 68 return i; 69 } 70 return -1; 71 } 72 ///返回頂點s的(相對於w的)下一個鄰接頂點 73 ///若w是s的最后一個鄰接頂點,則返回-1 74 int nextVex(Graph G,int s,int w){ 75 for(int i = w+1; i < G.numv; i++){ 76 if(G.arc[s][i] == 1) 77 return i; 78 } 79 return -1; 80 } 81 ///遞歸法 深度優先遍歷 82 void dfs(Graph G,int s){///從位置為s的頂點開始遍歷 83 for(int w=firstVex(G,s);w!=-1;w=nextVex(G,s,w)){ 84 if(!visit[w]){ 85 printf("%4s",G.vex[w]); 86 visit[w] = 1; 87 dfs(G,w); 88 } 89 } 90 } 91 92 int r[ARC],F=0,R=0; 93 ///遞歸法 廣度優先遍歷 94 void bfs(Graph G,int s){ 95 ///判斷根節點是否已經遍歷 96 if(!visitQ[s]){ 97 printf("%4s",G.vex[s]); 98 visitQ[s] = 1; 99 } 100 ///遍歷根節點s的鄰接點 101 102 for(int i = 0; i < G.numv; i++){ 103 if(!visitQ[i] && G.arc[s][i]){ 104 printf("%4s",G.vex[i]); 105 visitQ[i] = 1; 106 r[R++] = i; 107 } 108 } 109 ///遞歸遍歷s的鄰接點 110 if(F<R) bfs(G,r[F++]); 111 } 112 113 ///廣度優先遍歷(非遞歸) 114 int q[2*ARC],Fq=0,Rq=0; 115 int visit_q[2*ARC]; 116 void bfs_ND(Graph G,int s){ 117 int node; 118 q[Rq++] = s; 119 while(Fq < Rq){ 120 node = q[Fq++]; 121 if(!visit_q[node]){ 122 printf("%4s",G.vex[node]); 123 visit_q[node] = 1; 124 ///將頂點node的鄰接點入隊列 125 for(int i = 0; i < G.numv; i++){ 126 if(!visit_q[i] && G.arc[node][i]) 127 q[Rq++] = i; 128 } 129 } 130 } 131 } 132 133 int main(void){ 134 Graph G; 135 create(G); 136 output(G); 137 printf("請輸入遍歷的起始頂點:\n"); 138 char s[N]; 139 scanf("%s",s); 140 for(int i = 0; i < G.numv; i++) 141 visit[i] = visit_q[i] = 0; 142 printf("遞歸 深度優先遍歷:\n"); 143 printf("%4s",s); visit[getIndex(G,s)] = 1; 144 dfs(G,getIndex(G,s)); 145 printf("\n遞歸 廣度優先遍歷:\n"); 146 bfs(G,getIndex(G,s)); printf("\n"); 147 printf("非遞歸 廣度優先遍歷:\n"); 148 bfs_ND(G,getIndex(G,s)); printf("\n"); 149 return 0; 150 }

測試數據:
8 9
v1 v2 v3 v4 v5 v6 v7 v8
v1 v2
v1 v3
v2 v4
v2 v5
v3 v6
v3 v7
v4 v8
v5 v8
v7 v6
v1
