先导知识:

  数组、栈、队列、树、图等基本数据结构

  图论基本知识

正文:

  通过一个小例子,我们来理解BFS的思想。

  

   如上图,这是一棵树,树具有明显的层次关系,我们如果要遍历这棵树,有两种方法可选。

  一种就是从1点,选择其中的枝杈,一直遍历到底,如果到底了,我们就回退到上一个节点,选择另一条路径。已经走过的节点我们在地图上标记出来,重复以上的过程,直至遍历过所有的节点为止。

  一种可能的路径选择为1->2->5->6->3->7->4->8

  这种策略我们一般称为带回溯的深度优先搜索方法(DFS)。

  而另一种策略就是,从树的根节点开始,逐层遍历,先从最近的节点开始,一层层遍历,直至遍历到最后一层最后一个节点。

  一种可能的路径选择为1->2->3->4->5->6->7->8

  注意我们所说的“层”,在空间上是连续的,在遍历的时间中,他们不一定是连续的。

  这种策略即是广度优先搜索(BFS)。

  一种更直观的理解方式是在网状结构的任意节点(如下图)

  

  可以看到,中部的红色节点逐渐“侵蚀”周围的节点的过程

代码示例:

 

 1 int visited[SIZE][SIZE];//确保每个节点只访问一次,否则会死循环
 2 char chestDisk[SIZE][SIZE+2];//要搜索的“图”
 3 int dx[] = {0, 0, 1, -1};
 4 int dy[] = {-1, 1, 0, 0};//这两个数组枚举出了该元素与下层元素之间的所有情况
 5 bool BFS(int chest, int i, int j){
 6     int x,y;
 7     queue<pair<int, int> > que;//使用队列来确保层次
 8     que.push(make_pair(i,j));//初始状态入队
 9     int count = 0;//可能的控制变量
10     while(!que.empty()){//循环控制条件,队列不为空,队列内部也可有其他终止循环的条件
11         pair<int, int> temp = que.top();//取队首元素
12         que.pop();//出队
13         for(int i = 0;i < 4; i ++){
14                 x = dx[i] + temp.first;
15                 y = dy[i] + temp.second;
16                 if(0<=x<SIZE&&0<=y<SIZE&&!chestDisk[x][y]!='#'){//该点满足条件
17                     if(!visited[i][j]){//该点未访问过
18                         visited[x][y] = 1;
19                         que.push(make_pair(x,y));//将下一层的点入队
20                         count++;//控制变量变化
21                     }
22                 }
23
24         }
25     }
26     return count>=chest;//返回一个判断条件
27 }

适用范围:

  图结构的层次搜索——如寻找迷宫出口

  例题:poj1321

  对某一对象,寻找与其相似特征的其他对象,最终推演出结果

  例题:LeetCode:word-ladder

  迭代方式固定,求初始状态经过多少次迭代可以到达目标状态

  例题:poj3278

12-23 23:58
查看更多