当前位置: 首页 > news >正文

[算法日志]图论: 广度优先搜索(BFS)

[算法日志]图论: 广度优先搜索(BFS)

广度优先概论

​ 广度优先遍历也是一种常用的遍历图的算法策略,其思想是将本节点相关联的节点都遍历一遍后才切换到相关联节点重复本操作。这种遍历方式类似于对二叉树节点的层序遍历,即先遍历完子节点后再去遍历子节点的各个子节点。

代码框架

int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 表示四个方向
// grid 是地图,也就是一个二维数组
// visited标记访问过的节点,不要重复访问
// x,y 表示开始搜索节点的下标
void bfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int x, int y) {
    queue<pair<int, int>> que; // 定义队列
    que.push({x, y}); // 起始节点加入队列
    visited[x][y] = true; // 只要加入队列,立刻标记为访问过的节点
    while(!que.empty()) { // 开始遍历队列里的元素
        pair<int ,int> cur = que.front(); 
        que.pop(); // 从队列取元素
        int curx = cur.first;
        int cury = cur.second; // 当前节点坐标
        for (int i = 0; i < 4; i++) { // 开始想当前节点的四个方向左右上下去遍历
            int nextx = curx + dir[i][0];
            int nexty = cury + dir[i][1]; // 获取周边四个方向的坐标
            if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue;  // 坐标越界了,直接跳过
            if (!visited[nextx][nexty]) { // 如果节点没被访问过
                que.push({nextx, nexty});  // 队列添加该节点为下一轮要遍历的节点
                visited[nextx][nexty] = true; // 只要加入队列立刻标记,避免重复访问
            }
        }
    }
}

通过队列辅助进行迭代操作是BFS的常用遍历手段(当然也可以使用栈),而除了会额外使用一个visited数组辅助进行路径判断,其他的步骤都可以照搬二叉树的层序遍历。

BFS的简单应用

leetcode 200(岛屿数量)

BFS示例代码

 	const int dir[4][2] = { {0, -1}, {1, 0}, {0, 1}, {-1, 0} };
	void BFS(const vector<vector<char>>& g, vector<vector<bool>>& v, queue<pair<int,int>>& h)
	{
		while (!h.empty())
		{
			int X = h.front().first;
			int Y = h.front().second;
			h.pop();
			for (int i = 0; i < 4; ++i)
			{
				int nextX = X + dir[i][0];
				int nextY = Y + dir[i][1];
				if (nextX < 0 || nextY < 0 || nextX >= g[0].size() || nextY >= g.size())
					continue;
				if (!v[nextY][nextX] && g[nextY][nextX] == '1')
				{
					v[nextY][nextX] = true;
					h.push(pair<int, int>(nextX, nextY));
				}
			}
		}
		return;
	}
	int numIslands(const vector<vector<char>>& gird)
	{
		if (gird.empty())
			return 0;
		vector<vector<bool>> visited(gird.size(), vector<bool>(gird[0].size(), false));
		queue<pair<int, int>> help;
		int count = 0;
		for (int i = 0; i < gird.size(); ++i)
			for (int j = 0; j < gird[0].size(); ++j)
			{
				if (!visited[i][j] && gird[i][j] == '1')
				{
					++count;
					help.push({j, i});
					visited[i][j] = true;
					BFS(gird, visited, help);					
				}
			}
		return count;
	}

当然,对于这种岛屿问题并没有对遍历方式做限制,因此自然有DFS解法。

	const int dir[4][2] = { {0, -1}, {1, 0}, {0, 1}, {-1, 0} };
	void DFS2(vector<vector<bool>>& v, int& c,int depth ,int nextX, int nextY)
	{
		if (depth > 0 && (nextX < 0 || nextY < 0 || nextX >= v[0].size()
			|| nextY >= v.size() || v[nextY][nextX]))
			return;
		for(int i = nextY; i < v.size(); ++i)
			for (int j = nextX; j < v[0].size(); ++j)
			{
				if (v[i][j])
				{
					if (depth > 0)
						return;
					continue;
				}
				if (depth == 0)
					++c;
				v[i][j] = true;
				for (int k = 0; k < 4; ++k)
				{
					DFS2(v, c, depth + 1, j + dir[k][0], i + dir[k][1]);
				}
			}
		return;
	}
	int numIslands1(const vector<vector<char>>& grid)
	{
		if (grid.empty())
			return 0;
		vector<vector<bool>> visited(grid.size(), vector<bool>(grid[0].size()));
		int count = 0;
		for (int i = 0; i < grid.size(); ++i)
			for (int j = 0; j < grid[0].size(); ++j)
			{
				if (grid[i][j] == '1')
					visited[i][j] = false;
				else
					visited[i][j] = true;
			}
		DFS2(visited, count, 0, 0, 0);
		return count;
	}

相关文章:

  • NtripShare Caster高精度定位CORS服务软件
  • 【实践篇】一次Paas化热部署实践分享 | 京东云技术团队
  • 图像切分:将一张长图片切分为指定长宽的多张图片
  • element-ui 表格 点击选中
  • 中文大语言模型汇总
  • 城市内涝解决方案:实时监测,提前预警,让城市更安全
  • ESXi配置两个不同网段虚拟机互通
  • 考研408-计算机网络 第一章-计算机网络体系结构学习笔记及习题
  • 工具介绍——第三方软件远程连接(工具:Rustdesk)
  • 长短期神经网络LSTM的博文分类,长短期神经网络的原理分析
  • 【开题报告】基于uniapp的在线考试小程序的设计与实现
  • Python武器库开发-常用模块之subprocess模块(十九)
  • 技术分享 | App常见bug解析
  • CVE-2023-34040 Kafka 反序列化RCE
  • 【GEE】7、利用GEE进行遥感影像分类【随机森林分类】
  • 10 路由协议:西出网关无故人,敢问路在何方
  • 2、Sentinel基本应用限流规则(2)
  • Linux下Jenkins自动化部署SpringBoot应用
  • Java - Hutool 获取 HttpRequest:Header、Body、ParamMap 等利器
  • WebSocket Day03 : SpringMVC整合WebSocket
  • 安徽凤阳县明中都鼓楼楼宇顶部瓦片部分脱落,无人员伤亡
  • 中美博弈新阶段,这个“热带中国”火了
  • 以开放促发展,以发展促开放,浙江加快建设高能级开放强省
  • 河南发布高温橙警:郑州、洛阳等地最高气温将达40℃以上
  • 多图|多款先进预警机亮相雷达展,专家:中国预警机已达世界先进水平
  • 倒票“黄牛”屡禁不绝怎么破?业内:强化文旅市场票务公开制度