鄰接矩陣 + 深度優先遍歷 + 廣度優先遍歷


 
 
  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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM