一、广度优先搜索(BFS: Breadth-First-Search)
1.1 BFS的概念
广度优先算法是一种图形搜索算法。从图的某一结点出发,首先依次访问该结点的所有邻接顶点
再按这些顶点被访问的先后次序依次访问与它们相邻接的所有未被访问的顶点。重复此过程直至所有顶点均被访问为止。
如下例:起点V1,找到目标结点V8
上图广度优先算法的遍历顺序为:
可以看出:
BFS是一层层进行的,沿着树的宽度遍历数的结点。它并不考虑结果的可能地址,彻底地搜索整张图,直到找到结果为止。
二、岛屿数量实例
2.1 题目描述
给定一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
2.2 思路分析
假设题目输入为:
我们把结点定义为(x,y)。于是起点为(0,0),终点为(3,4)
题干说,陆地是由‘1’ 水平方向和垂直方向相邻而成。那我们可以把题目转变为找1的树状图。
整理后的题目要求:
- 起点Vs为(0,0)
- 终点Vd为(3,4)
- 求1的树状图的个数(一个树状图中间要求没有断开)
为了防止重复搜索,我们应该设置一个visited数组,用来标记元素是否访问。
该输入可以看出为一个岛屿,则最后搜索出的结果应该如下图(遍历的顺序也如图):
三、完整代码及注释
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
//特别注意防止空输入
if(grid.empty()){
return 0;
}
//初始化行和列
int rows = grid.size();
int cols = grid[0].size();
if (rows == 0 || cols == 0) {
return 0;
}
//定义方向(上下左右)
int dx[] = { -1,0,1,0 };
int dy[] = { 0,1,0,-1 };
//定义计数变量
int counts=0;
//定义bool访问数组和用于实现BFS的队列
vector<vector<bool> > visited(rows, vector<bool>(cols, false));
queue<pair<int, int> > que;
//主要过程
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
//如果为1且没有被访问过
if ( grid[i][j] == '1' && visited[i][j]==false) {
que.push(make_pair(i, j));
counts++;
visited[i][j] = true;
//BFS
while (!que.empty()){
int x = que.front().first;
int y = que.front().second;
que.pop();
//寻找出队结点上下左右的坐标,如果没有访问且为1,并且没有出界则加入队列
for (int k = 0; k < 4; k++) {
int xx = x + dx[k];
int yy = y + dy[k];
//特别注意xx不能等于rows,yy同理
//xx<rows由两层for循环的遍历顺序决定
if(xx>=0 && xx<rows && yy>=0 && yy<cols){
if (grid[xx][yy] == '1'&&visited[xx][yy] == false) {
visited[xx][yy] = true;
que.push(make_pair(xx, yy));
}
}
}
}
}
}
}
return counts;
}
};