1.宽度优先搜索算法原理
如上图,搜索的顺序可以用队列来模拟
2.准备知识:队列
queue <int> q;//定义队列
q.push(1);//入队
q.push(2);
q.push(3);
cout<<q.front()<<endl;//输出队首元素
cout<<q.back()<<endl; //输出队尾元素
q.pop();//弹出队首元素
cout<<q.empty()<<endl;//队列为空,则为1
3.宽度优先搜索例题
(1)题目:下图中是5*5的地面上铺设了瓷砖,旗子的位置是出发点,笑脸的位置不能到达,空的格子可走的,输出从起始位置出发一共可走的瓷砖数。
(2)实现逻辑,这是一道典型的宽度优先题目,在题目中起始点标识为‘@’,笑脸标识为‘#’,空格子标识为‘.’,
主函数逻辑分三步:读入瓷砖数据;搜索瓷砖;输出数量。
搜索函数逻辑为1.将起点加入到队列中;2.如果队列不为空,开始搜索入队列,当前位置的上下左右 依次入队列 ,入队列时需要判断是否越界,是否是"." 3.弹出队首元素;4.直到队列为空,结束搜索
(3)代码实现
#include<iostream>
#include<queue>
using namespace std;
int w,h;//瓷砖宽和高
char room[100][100];//存放瓷砖数据
int x0,y0;//起点位置
int num;//记录一共有多少可走的瓷砖
int d[4][2]={{0,-1},{0,1},{-1,0},{1,0}};//上下左右算坐标
struct node{
int x;
int y;
};
bool check(int x,int y){
if(x>=0&&x<h&&y>=0&&y<w) return 1;
else return 0;
}
void bfs(int x,int y){
//逻辑如下:
//1.将起点加入到队列中;
//2.如果队列不为空,开始搜索入队列,当前位置的上下左右 依次入队列
//入队列时需要判断是否越界,是否是"."
//3.弹出队首
//4.直到队列为空,结束搜索
num=1;//起点也是可走的瓷砖,所以赋值位1
queue <node> brick;
node start,next;
start.x=x,start.y=y;
brick.push(start);//将起点加入到队列中;
while(!brick.empty()){//搜索入队列,当前位置的上下左右 依次入队列
for(int i=0;i<4;i++){
start =brick.front();
next.x=start.x+d[i][0];
next.y=start.y+d[i][1];
if(check(next.x,next.y)&&room[next.x][next.y]=='.'){//断是否越界,是否是"."
brick.push(next);
num++;
room[next.x][next.y]='#';
}
}
brick.pop();
}
}
int main(){
//主函数逻辑分三步:读入瓷砖数据;搜索瓷砖;输出数量
//1.读入矩阵数据 for循环,并记录起点位置
cin>>w>>h;
for(int i=0;i<w;i++){
for(int j=0;j<h;j++) {
cin>>room[i][j];
if(room[i][j]=='@'){
x0=i;
y0=j;
}
}
}
//2.用宽度优先算法搜索
bfs(x0,y0);
//3.输出个数
cout<<num;
return 0;
}
(4)运行结果