详解广度优先搜索(顺便学习C++的队列STL,也有一部分深搜的东西)

一、C++的队列STL

广度优先搜索一般是用队列来实现的,首先学习一下C++自己带的queue:

queue模板类定义在头文件中,用queue q申明一个元素类型是data_type的队列

基本操作:

(1)q.empty();判断队列是不是为空,若为空返回1

(2)q.size();返回队列长度

(3)q.push(x);入队

(4)q.pop();出队

(5)q.front();访问队首元素

(6)q.back();访问队尾元素


二、什么是广度优先

步步为营的搜索,一次只走一步,并且要把相同距离的都走完再走下一步。有一个用到了广搜的题,在博文《最短路径算法》里:http://blog.csdn.net/lishichengyan/article/details/76944221,其中无权图的最短路径算法就是一个广度优先。


三、框架

与其说有框架,不如说有一个大致流程...毕竟深搜/广搜都是需要具体问题具体分析的。。

用一个队列,把当前点加进去,从这个点开始尝试所有可能的方向,尝试完以后把这个点出队,然后对还在队里的点(也就是刚才入队的点)继续同样的步骤,直到达到目的。


四、实例

(1)无向图的最短路径

参看上面的博文

(2)经典的问题:Counting Islands

给一张地图,如:

1 0 0 0 0 0 0 0

1 0 0 1 1 1 0

0 0 1 1 1 1 0 0

0 0 0 0 1 1 0 0

0 1 1 0 0 0 0 0

用1表示陆地,0表示海水,被水围起来的区域称为“岛屿”。假设现在你处在(1,3)点(上图中标红加粗处),编写程序计算你所在岛屿的面积,图用二维数组储存,下标均从0开始。

输入:

5 8 3 1

1 0 0 0 0 0 0 0

1 0 0 1 1 1 1 0

0 0 1 1 1 1 0 0

0 0 0 0 1 1 0 0

0 1 1 0 0 0 0 0

其中5,8表示图的行和列,3,1表示你所处的横纵坐标,请输出正确的面积(在这个问题中是10)

#include
using namespace std;

#define MAX 51
#define QSIZE 2501

struct pos{
	int x;
	int y;
};

int book[MAX][MAX]={0};//标记有没有被访问过
int map[MAX][MAX];

int main(){
	int startx,starty,row,col,res=1;
	struct pos q[QSIZE];
	int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
	int front=0,rear=0;
	cin>>row>>col>>startx>>starty;
	for(int i=0;i>map[i][j];
	q[rear].x=startx;
	q[rear].y=starty;
	book[startx][starty]=1;
	rear++;
	while(front!=rear){
		int tx,ty;
		for(int k=0;k<4;k++){
			tx=q[front].x+next[k][0];
			ty=q[front].y+next[k][1];
			if(tx<0||tx>=row||ty<0||ty>=col)
				continue;
			if(map[tx][ty]==1&&book[tx][ty]==0){
				res++;
				book[tx][ty]=1;
				q[rear].x=tx;
				q[rear].y=ty;
				rear++;
			}
		}
		front++;//dequeue
	}
	cout<<"the area of the island:"<
详解广度优先搜索(顺便学习C++的队列STL,也有一部分深搜的东西)_第1张图片

这个问题也可以用深搜解答,这里不写了。

现在把问题变动一下:要求给一张图,求出这张图里独立岛屿的个数。

例如上面的图:

1 0 0 0 0 0 0 0

1 0 0 1 1 1 1 0

0 0 1 1 1 1 0 0

0 0 0 0 1 1 0 0

0 1 1 0 0 0 0 0

独立岛屿有3个

解决这个问题的经典算法叫做“着色法”,对不同的岛屿涂上不同的颜色,最后返回颜色的数量即可:

#include
using namespace std;

#define MAX 51
#define QSIZE 2501

int row,col;
int book[MAX][MAX]={0};
int map[MAX][MAX];

void dfs(int x,int y,int color){
	int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
	map[x][y]=color;
	for(int k=0;k<4;k++){
		int tx=x+next[k][0];
		int ty=y+next[k][1];
		if(tx<0||tx>row-1||ty<0||ty>col-1)
			continue;
		if(map[tx][ty]==1&&book[tx][ty]==0){
			book[tx][ty]=1;
			dfs(tx,ty,color);
		}
	}
	return;
}

int main(){
	int color=0;
	cin>>row>>col;
	for(int i=0;i>map[i][j];
	for(int i=0;i
详解广度优先搜索(顺便学习C++的队列STL,也有一部分深搜的东西)_第2张图片

注:上图的第一行输入是图的行列




你可能感兴趣的:(数据结构与算法分析)