BFS(广度优先搜索)

在这里插入图片描述

BFS(广度优先搜索)

1. 什么是BFS

宽度优先搜索(BFS) :同样是一种遍历搜索树或图的算法。遍历方式为选定一个节点,接着访问所有与当前节点连接的满足条件的点。接着从这些可访问点中,按照相同的遍历方式访问每个节点,直到所有节点都被访问,这与树的层次遍历相同,时间复杂度与 DFS 相同,与搜素树和图的节点树相关。 BFS 一般用于解决最短路径,最短步骤等最优问题。

2. BFS的搜索顺序

BFS为逐层遍历,一层一层的搜索状态

在这里插入图片描述

利用BFS进行搜索的结果为:7 1 5 20 33 9 0 15 31 2 0 3 25
(搜索完第一层,则继续搜索第二层,第二层搜索完之后,才搜索第三层)

3. BFS采用的数据结构

实现BFS所采用的数据结构为 队列(queue)

4.DFS与BFS的区别

DFS为深度优先搜索,一条路走到底再回头
BFS为广度优先搜索,每一层遍历完之后再遍历下一层

注意由于深度优先搜索会优先考虑搜索的深度。形象点说,就是不找到一个答案不回头。当答案在整棵解答树中比较稀疏时,深度优先搜索可能会先陷人过深的情况,一时半会儿找不到解。有时候需要解决连通性、最短路问题时,可以考虑使用广度优先搜索

5. BFS的常规模板

5.1 文字描述

BFS算法的实现是利用队列
需重复执行以下操作

  1. 将根节点入队
  2. 取出队头元素
  3. 将队头元素能遍历到的所有状态全部入队

直至全部搜索完毕

5.2 代码展示

Q.push(初始状态)// 将初始状态入队
while(!Q.empty())
{
	State u = Q.front(); // 取出队首
	Q.pop(); // 出队
	for(枚举所有可扩展状态) // 找到 u 的所有可达状态 v
		if(是合法的) // v 需要满足某些条件,如未访问过或未在队内等
			Q.push(v); // 入队(同时可能需要维护某些必要信息)
}

6. 例题刨析

洛谷 P1443 马的遍历

6.1 文字简述

先建立一个结构体数组用于存储扩展的结点。先让起点人队,然后在队列取状态逐个扩展。容易被证明每个点被扩展到时一定是最少步数。又因为每个点只被扩展了一次,所以复杂度是 O (mn)。

6.2 代码展示

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define maxn 310

struct coord { // 建立结构体用于存储 x,y 两个坐标
	int x, y;
};
queue<coord> Q; // 队列
int ans[maxn][maxn]; // 用于记录答案,-1 表示未访问
int walk[8][2] = {{2, 1}, {1,2}, {-1, 2}, {-2,1}, {-2, -1},{-1, -2}, {1, -2}, {2, -1}}; 
// 马能走的8个方向

int main()
{
	int n, m, sx, sy;
	memset (ans, -1, sizeof(ans));
	cin >> n >> m >> sx >> sy;
	coord tmp = {sx, sy};
	Q.push(tmp); // 使起点入队
	ans[sx][sy] = 0;
	while(!Q.empty()) // 一直循环,直到队列为空
	{ 
		coord u = Q.front(); // 取出队首
		int ux = u.x, uy = u.y;
		Q.pop();
		for(int k = 0; k < 8; k++){
			int x = ux + walk[k][0], y = uy + walk[k][1];
			int d = ans[ux][uy];
			if(x < 1 || x > n || y < 1 || y > m || ans[x][y] != -1)
			    continue; // 如若坐标超过地图范围或者该点已经被访问则不需要入队
			ans [x][y] = d + 1; // 记录答案,是上一个点多走一步的结果
			coord tmp = {x, y};
			Q.push(tmp);
		}
	}
	for(int i = 1; i <= n; i++, puts(" "))
	    for(int j = 1; j <= m; j++)
	        printf("%-5d", ans[i][j]); // 根据题意,按照格式输出
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值