综上,上图的DFS是按照如下顺序进行的: A->B->D->H->E->H->D->B->A->C->F->G->F->C->A 其中,红色部分代表首次访问,在这部分顶点被访问后,我们便将visited数组的对应元素设为true,表明这些顶点已经被访问过了,因此我们可以得到深度优先搜索得到的顺序为:
A->B->D->H->E->C->F->G 深度优先搜索的代码实现如下:
-
-
-
- void DFS(Graph Gp, int begin)
- {
-
- printf("%c ",Gp[begin].data);
- visited[begin] = true;
-
-
- int i;
- for(i=first_vertex(Gp,begin); i>=0; i=next_vertex(Gp,begin,i))
- {
- if(!visited[i])
- DFS(Gp,i);
- }
- }
-
-
-
-
- void DFS_traverse(Graph Gp,int begin)
- {
- int i;
- for(i=0;i<NUM;i++)
- visited[i] = false;
-
-
- DFS(Gp,begin);
-
- for(i=0;i<NUM;i++)
- {
- if(!visited[i])
- DFS(Gp,i);
- }
- }
这里调用了first_vertex()和next_vertex()两个函数,根据如上图手绘的邻接表的存储结构,这两个函数代码实现及详细注释如下:-
-
-
- int first_vertex(Graph Gp,int pos)
- {
- if(Gp[pos].first)
- return Gp[pos].first->vertex;
- else
- return -1;
- }
-
-
-
-
-
- int next_vertex(Graph Gp,int pos,int cur)
- {
- Node *p = Gp[pos].first;
-
- while(p->vertex != cur)
- p = p->pNext;
-
-
- if(p->pNext)
- return p->pNext->vertex;
- else
- return -1;
- }
广度优先搜索 广度优先搜索(BFS)类似于树的层序遍历(如尚未掌握图的先序遍历,请移步这里:http://blog.csdn.net/ns_code/article/details/13169703)。其基本思想是:从头图中某个顶点v出发,访问v之后,依次访问v的各个未被访问的邻接点,而后再分别从这些邻接点出发,依次访问它们的邻接点,直到图中所有与v连通的顶点都已被访问。如果当前图只是需要遍历的非连通图的一个极大连通子图,则另选其他子图中的一个顶点,重复上述遍历过程,直到该非连通图中的所有顶点都被遍历完。很明显,跟树的层序遍历一样,图的广度优先搜索要用到队列来辅助实现。 同样以上面的例子来分析,假设从A点开始遍历该图,根据图中顶点的存储关系,会按照下面的步骤来遍历该图: 1、在访问完顶点A后,首先访问A的第一个邻接点B,而后访问A的第二个邻接点C; 2、再根据顺序访问B的未被访问的邻接点,先访问D,后访问E; 3、再根据顺序访问C的未被访问的邻接点,先访问F,在访问G; 4、而后一次访问D、E、F、G等顶点的未被访问的邻接点; 5、D的邻接点中,只有H未被访问,因地访问H; 6、E、F、G、H等都没有未被访问的邻接点了,遍历到此结束。 综上,我们可以得到广度优先搜索得到的顺序为:A->B->C->D->E->F->G->H 深度优先搜索的代码实现如下:
-
-
-
- void BFS_traverse(Graph Gp,int begin)
- {
- int i;
- for(i=0;i<NUM;i++)
- visited[i] = false;
-
-
- BFS(Gp,begin);
-
- for(i=0;i<NUM;i++)
- { if(!visited[i])
- BFS(Gp,i);
- }
- }
-
-
-
-
- void BFS(Graph Gp,int begin)
- {
-
- printf("%c ",Gp[begin].data);
- visited[begin] = true;
-
- int i;
- int pVertex;
- PQUEUE queue = create_queue();
- en_queue(queue, begin);
- while(!is_empty(queue))
- {
- de_queue(queue,&pVertex);
-
- for(i=first_vertex(Gp,pVertex); i>=0; i=next_vertex(Gp,pVertex,i))
- {
- if(!visited[i])
- {
- printf("%c ",Gp[i].data);
- visited[i] = true;
- en_queue(queue,i);
- }
- }
- }
-
- destroy_queue(queue);
- }
遍历结果 按照上面的例子来构建图,而后采用如下代码测试DFS和BFS的输出结果: -
-
-
-
-
- #include<stdio.h>
- #include<stdlib.h>
- #include "data_structure.h"
-
- int main()
- {
- Graph Gp = create_graph();
-
-
- printf("对图进行深度优先遍历:\n");
- printf("从顶点A出发DFS的结果:");
- DFS_traverse(Gp,0);
- printf("\n");
- printf("从顶点H出发DFS的结果:");
- DFS_traverse(Gp,7);
- printf("\n");
- printf("从顶点E出发DFS的结果:");
- DFS_traverse(Gp,4);
- printf("\n");
- printf("\n");
-
-
- printf("对图进行深度优先遍历:\n");
- printf("从顶点A出发BFS的结果:");
- BFS_traverse(Gp,0);
- printf("\n");
- printf("从顶点H出发BFS的结果:");
- BFS_traverse(Gp,7);
- printf("\n");
- printf("从顶点E出发BFS的结果:");
- BFS_traverse(Gp,4);
- printf("\n");
-
- int i;
-
- for(i=0;i<NUM;i++)
- {
- free(Gp[i].first);
- Gp[i].first = 0;
- }
-
-
- free(Gp);
- Gp = 0;
- return 0;
- }
测试得到的输出结果如下:
完整代码下载
完整的C语言实现代码下载地址:http://download.csdn.net/detail/mmc_maodun/6946859
本文地址:http://blog.csdn.net/ns_code/article/details/19617187 |