(边自学边写,还真有点累啊,)

注:以下代码均为部分,关于图的表示方法参看我的博客:

http://www.cnblogs.com/dzkang2011/p/graph_1.html

 

一、广度优先搜索

  广度优先搜索(BFS)是最简单的图搜索算法之一,也是很多重要的图算法的原型。在Prim最小生成树算法和Dijkstra单源最短路径算法中,都采用了与广度优先搜索类似的思想。

  在给定图G=(V,E)和一个特定的源顶点s的情况下,广度优先搜索系统地探索G中的边,以期发现可以从s到达的所有顶点,并计算s到所有这些可达顶点之间的距离(即最少的边数)。该搜索算法同时还能生成一棵根为s、且包括所有s的可达顶点的广度优先树。对从s可达的任意顶点v,广度优先树中从s到v的路径对应于图G中从s到v的一条最短路径,即包含最少边数的路径。该算法对有向图和无向图同样适用。之所以称为广度优先搜索,是因为它始终是将已发现和未发现顶点之间的边界,沿其广度方向向外扩展。亦即,算法首先发现和s距离为k的所有顶点,然后才会发现和s距离为k+1的其他顶点。

  在广度优先搜索中,我们首先要注意一个顶点的3种状态:

  已到达(已访问)但还未考察:表示当前搜索到的这个顶点,接下来要对这个顶点进行分析。

  正在考察:已经到达了这个顶点,但是它的相邻顶点还没有完全被访问到,称为未考察完成。采用队列存储未被考察的顶点。

  已考察:已经到达了这个顶点,且它的所有相邻顶点都已经被访问完成,则称该顶点已考察。

  具体步骤如下:

  (1)从顶点s开始,标记它为已访问,将其压入队列中;

  (2)这时,顶点s的的相邻顶点还未被访问,所以s暂时还为未考察状态;

  (3)访问它的所有相邻顶点,并将它们压入队列,之后s的状态变为已考察,将其从队列中删除;这些入队的顶点的父亲顶点即为s

  (4)取队头顶点,以其为起点重复进行以上操作。当所有的顶点都被考察完毕,即队列为空时,考察停止。

  由分析可知,广度优先搜索的总运行时间为O(V+E),为一个线性时间。

   

      最短路径:源顶点为s,d[v]中保存从s到v的最短路径长度

      广度优先树:过程BFS在搜索图的同时,也建立了一棵广度优先树,这棵树是用parent[]表示的,parent[v]表示的是顶点v的父亲结点。

图基本算法 图搜索(广度优先、深度优先)

广度优先搜索C++(邻接表)实现:

 1 #define INF 9999
 2 bool visited[maxn];         //标记顶点是否被考察,初始置为false
 3 int d[maxn], parent[maxn];  //d[]记录最短路径长度,parent[]记录某结点的父亲结点,生成树
 4 void bfs(int s)             //广度优先搜索,邻接表输入(详见“一、图的表示”)
 5 {
 6     for(int i = 1; i <= n; i++) //初始化
 7     {
 8         d[i] = INF;
 9         parent[i] = -1;
10         visited[i] = false;
11     }
12     visited[s] = true;
13     d[s] = 0;
14     queue<int> q;        //用STL队列实现 ,#include <queue>
15     q.push(s);           //压入队列
16     while(!q.empty())
17     {
18         int u = q.front();          //取队头元素
19         arcnode * p = Ver[u].firarc;
20         while(p != NULL)        //遍历相邻顶点
21         {
22             if(!visited[p->vertex])
23             {
24                 q.push(p->vertex);  //压入队列
25                 parent[p->vertex] = u;  //指向父亲
26                 d[p->vertex] = d[u]+1;  //路径长+1
27                 visited[p->vertex] = true;   //置为已被考察
28             }
29             p = p->next;
30         }
31         q.pop();        //出队列
32     }
33 }
34 void PrintPath(int s, int v)    //打印从s到v的最短路径,需先调用bfs(s)
35 {
36     if(v == s)
37         cout << s << endl;
38     else if(parent[v] == -1)
39         return;
40     else
41     {
42         PrintPath(s,parent[v]);
43         cout << v << endl;
44     }
45 }
View Code

相关文章:

  • 2021-08-19
  • 2021-08-24
  • 2021-08-11
  • 2021-06-29
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-10-31
  • 2021-03-30
  • 2021-06-06
  • 2022-12-23
  • 2021-09-20
  • 2022-12-23
  • 2021-09-13
相关资源
相似解决方案