图的深度优先遍历

  1 /**
  2  * C: 邻接矩阵图表示的"无向图(Matrix Undirected Graph)"
  3  *
  4  */
  5 
  6 #include <stdio.h>
  7 #include <stdlib.h>
  8 #include <malloc.h>
  9 #include <string.h>
 10 
 11 #define MAX 100
 12 #define isLetter(a)  ((((a)>='a')&&((a)<='z')) || (((a)>='A')&&((a)<='Z')))
 13 #define LENGTH(a)  (sizeof(a)/sizeof(a[0]))
 14 
 15 // 邻接矩阵
 16 typedef struct _graph
 17 {
 18     char vexs[MAX];       // 顶点集合
 19     int vexnum;           // 顶点数
 20     int edgnum;           // 边数
 21     int matrix[MAX][MAX]; // 邻接矩阵
 22 }Graph, *PGraph;
 23 
 24 /*
 25  * 返回ch在matrix矩阵中的位置
 26  */
 27 static int get_position(Graph g, char ch)
 28 {
 29     int i;
 30     for(i=0; i<g.vexnum; i++)
 31         if(g.vexs[i]==ch)
 32             return i;
 33     return -1;
 34 }
 35 
 36 /*
 37  * 读取一个输入字符
 38  */
 39 static char read_char()
 40 {
 41     char ch;
 42 
 43     do {
 44         ch = getchar();
 45     } while(!isLetter(ch));
 46 
 47     return ch;
 48 }
 49 
 50 /*
 51  * 创建图(自己输入)
 52  */
 53 Graph* create_graph()
 54 {
 55     char c1, c2;
 56     int v, e;
 57     int i, p1, p2;
 58     Graph* pG;
 59     
 60     // 输入"顶点数"和"边数"
 61     printf("input vertex number: ");
 62     scanf("%d", &v);
 63     printf("input edge number: ");
 64     scanf("%d", &e);
 65     if ( v < 1 || e < 1 || (e > (v * (v-1))))
 66     {
 67         printf("input error: invalid parameters!\n");
 68         return NULL;
 69     }
 70     
 71     if ((pG=(Graph*)malloc(sizeof(Graph))) == NULL )
 72         return NULL;
 73     memset(pG, 0, sizeof(Graph));
 74 
 75     // 初始化"顶点数"和"边数"
 76     pG->vexnum = v;
 77     pG->edgnum = e;
 78     // 初始化"顶点"
 79     for (i = 0; i < pG->vexnum; i++)
 80     {
 81         printf("vertex(%d): ", i);
 82         pG->vexs[i] = read_char();
 83     }
 84 
 85     // 初始化"边"
 86     for (i = 0; i < pG->edgnum; i++)
 87     {
 88         // 读取边的起始顶点和结束顶点
 89         printf("edge(%d):", i);
 90         c1 = read_char();
 91         c2 = read_char();
 92 
 93         p1 = get_position(*pG, c1);
 94         p2 = get_position(*pG, c2);
 95         if (p1==-1 || p2==-1)
 96         {
 97             printf("input error: invalid edge!\n");
 98             free(pG);
 99             return NULL;
100         }
101 
102         pG->matrix[p1][p2] = 1;
103         pG->matrix[p2][p1] = 1;
104     }
105 
106     return pG;
107 }
108 
109 /*
110  * 创建图(用已提供的矩阵)
111  */
112 Graph* create_example_graph()
113 {
114     char vexs[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
115     char edges[][2] = {
116         {'A', 'C'}, 
117         {'A', 'D'}, 
118         {'A', 'F'}, 
119         {'B', 'C'}, 
120         {'C', 'D'}, 
121         {'E', 'G'}, 
122         {'F', 'G'}}; 
123     int vlen = LENGTH(vexs);
124     int elen = LENGTH(edges);
125     int i, p1, p2;
126     Graph* pG;
127     
128     // 输入"顶点数"和"边数"
129     if ((pG=(Graph*)malloc(sizeof(Graph))) == NULL )
130         return NULL;
131     memset(pG, 0, sizeof(Graph));
132 
133     // 初始化"顶点数"和"边数"
134     pG->vexnum = vlen;
135     pG->edgnum = elen;
136     // 初始化"顶点"
137     for (i = 0; i < pG->vexnum; i++)
138     {
139         pG->vexs[i] = vexs[i];
140     }
141 
142     // 初始化"边"
143     for (i = 0; i < pG->edgnum; i++)
144     {
145         // 读取边的起始顶点和结束顶点
146         p1 = get_position(*pG, edges[i][0]);
147         p2 = get_position(*pG, edges[i][1]);
148 
149         pG->matrix[p1][p2] = 1;
150         pG->matrix[p2][p1] = 1;
151     }
152 
153     return pG;
154 }
155 
156 /*
157  * 返回顶点v的第一个邻接顶点的索引,失败则返回-1
158  */
159 static int first_vertex(Graph G, int v)
160 {
161     int i;
162 
163     if (v<0 || v>(G.vexnum-1))
164         return -1;
165 
166     for (i = 0; i < G.vexnum; i++)
167         if (G.matrix[v][i] == 1)
168             return i;
169 
170     return -1;
171 }
172 
173 /*
174  * 返回顶点v相对于w的下一个邻接顶点的索引,失败则返回-1
175  */
176 static int next_vertix(Graph G, int v, int w)
177 {
178     int i;
179 
180     if (v<0 || v>(G.vexnum-1) || w<0 || w>(G.vexnum-1))
181         return -1;
182 
183     for (i = w + 1; i < G.vexnum; i++)
184         if (G.matrix[v][i] == 1)
185             return i;
186 
187     return -1;
188 }
189 
190 /*
191  * 深度优先搜索遍历图的递归实现
192  */
193 static void DFS(Graph G, int i, int *visited)
194 {                                   
195     int w; 
196 
197     visited[i] = 1;
198     printf("%c ", G.vexs[i]);
199     // 遍历该顶点的所有邻接顶点。若是没有访问过,那么继续往下走
200     for (w = first_vertex(G, i); w >= 0; w = next_vertix(G, i, w))
201     {
202         if (!visited[w])
203             DFS(G, w, visited);
204     }
205        
206 }
207 
208 /*
209  * 深度优先搜索遍历图
210  */
211 void DFSTraverse(Graph G)
212 {
213     int i;
214     int visited[MAX];       // 顶点访问标记
215 
216     // 初始化所有顶点都没有被访问
217     for (i = 0; i < G.vexnum; i++)
218         visited[i] = 0;
219 
220     printf("DFS: ");
221     for (i = 0; i < G.vexnum; i++)
222     {
223         //printf("\n== LOOP(%d)\n", i);
224         if (!visited[i])
225             DFS(G, i, visited);
226     }
227     printf("\n");
228 }
229 
230 /*
231  * 广度优先搜索(类似于树的层次遍历)
232  */
233 void BFS(Graph G)
234 {
235     int head = 0;
236     int rear = 0;
237     int queue[MAX];     // 辅组队列
238     int visited[MAX];   // 顶点访问标记
239     int i, j, k;
240 
241     for (i = 0; i < G.vexnum; i++)
242         visited[i] = 0;
243 
244     printf("BFS: ");
245     for (i = 0; i < G.vexnum; i++)
246     {
247         if (!visited[i])
248         {
249             visited[i] = 1;
250             printf("%c ", G.vexs[i]);
251             queue[rear++] = i;  // 入队列
252         }
253         while (head != rear) 
254         {
255             j = queue[head++];  // 出队列
256             for (k = first_vertex(G, j); k >= 0; k = next_vertix(G, j, k)) //k是为访问的邻接顶点
257             {
258                 if (!visited[k])
259                 {
260                     visited[k] = 1;
261                     printf("%c ", G.vexs[k]);
262                     queue[rear++] = k;
263                 }
264             }
265         }
266     }
267     printf("\n");
268 }
269 
270 /*
271  * 打印矩阵队列图
272  */
273 void print_graph(Graph G)
274 {
275     int i,j;
276 
277     printf("Martix Graph:\n");
278     for (i = 0; i < G.vexnum; i++)
279     {
280         for (j = 0; j < G.vexnum; j++)
281             printf("%d ", G.matrix[i][j]);
282         printf("\n");
283     }
284 }
285 
286 void main()
287 {
288     Graph* pG;
289 
290     // 自定义"图"(输入矩阵队列)
291     //pG = create_graph();
292     // 采用已有的"图"
293     pG = create_example_graph();
294 
295     print_graph(*pG);       // 打印图
296     DFSTraverse(*pG);       // 深度优先遍历
297     BFS(*pG);               // 广度优先遍历
298 }

 

posted on 2017-12-10 22:00  久久新秋  阅读(260)  评论(0)    收藏  举报

导航