数据结构与算法-搜索-bfs(floodfill and 最短路):池塘计数,城堡问题,山峰和山谷,迷宫问题,武士分度的牛,抓住那头牛
广度优先搜索
广度优先搜索(Breadth - First Search,BFS)是一种常用于图和树数据结构的搜索算法
核心概念:BFS是一种图搜索算法,用于在图或树中寻找特定节点或路径。它从起始节点开始,按照层级顺序逐层遍历图中的节点,直到找到目标节点或遍历完整个图。其核心思想是从图中的某一顶点V_0开始,先访问V_0;接着访问所有与V_0相邻接的顶点V_1,V_2,......,V_t;然后依次访问与V_1,V_2,......,V_t相邻接的所有未曾访问过的顶点,如此循环,直至所有顶点都被访问过。这种搜索次序体现了沿层次向横向扩展的趋势。
算法流程:
1. 初始化:创建一个队列用于存储待访问节点,一个集合用于记录已访问节点,将起始节点加入队列和已访问集合。
2. 访问节点:当队列不为空时,取出队列头部的节点进行访问(例如检查是否为目标节点等操作)。
3. 扩展节点:将该节点所有未被访问过的相邻节点加入队列,并标记为已访问。
4. 重复步骤:重复步骤2和3,直到队列为空或找到目标节点。
特点:
优点:可以找到从起始节点到目标节点的最短路径(在无权图中,每条边权重相同的情况下,这里的最短指最少边数);能遍历整个图,确保不会遗漏任何节点。
缺点:当图规模较大时,需要较大内存空间来存储遍历过程中的节点;对于有权图(每条边权重不同),可能不是最优解决方案。
应用场景:
- 无权图中查找最短路径或最少步骤的解决方案:如迷宫问题,从起点到终点寻找最短路线。 - 遍历整个图:例如在社交网络中,从某一用户出发,遍历其所有可到达的用户关系。 - 在图中查找特定节点或路径 :在网络拓扑结构中查找特定的设备节点等。
- 实现示例:在代码实现时,通常使用队列数据结构来保存待访问的节点,以保证按照先进先出的顺序进行遍历。
bfs的特点:
1.求‘最小’
2.基于迭代实现
floodfill模型
Flood - fill(漫水填充)是一种基于广度优先搜索(BFS)或深度优先搜索(DFS)思想的算法,常用于图像处理、游戏开发等领域
定义
Flood - fill 算法是在一个区域内,从给定的起始点开始,按照一定的规则(比如颜色相同、数值在某个范围内等),将周围符合条件的相邻位置进行填充或标记的过程。例如在一幅图像中,从某一个像素点出发,把和它颜色相同且相邻的像素点都标记出来,这就是一个简单的漫水填充应用。
原理:
利用队列来存储待处理的点。将起始点加入队列,然后从队列中取出点进行处理(填充或标记),并把它符合条件的相邻点加入队列,不断重复这个过程,直到队列为空。比如在填充一个封闭图形时,起始点入队后,每次从队列中取出一个像素点,若其颜色符合条件,将其填充为新颜色,再把它四周符合条件的像素点加入队列,直到队列中没有待处理的点。
可以在线性的时间里,找到所有的连通块
应用场景
图像处理:图像分割中,可根据像素的颜色、灰度等特征,使用 Flood - fill 算法将图像中相似区域划分出来;图像修复时,用于填充图像中的孔洞或缺失部分。比如在修复老照片时,对于照片上的污渍区域,可以利用 Flood - fill 算法将其替换为周围相似的像素值。
游戏开发:在游戏地图编辑中,用于填充地图中的特定区域,如给草地、水域等区域上色;碰撞检测中,判断某个区域是否被对象占据。例如在一个角色扮演游戏中,用 Flood - fill 算法来判断角色是否进入了某个特定的场景区域。
地理信息系统(GIS):对地理区域进行划分和分析,比如根据海拔高度、土地类型等属性,将相似的地理区域进行标记和归类。
当然,也可以使用dfs算法
习题1(池塘计数)floodfill:
分析:
这里的连通是8连通格
这是一道典型的基于图论或矩阵遍历的连通区域计数问题,核心在于统计字符矩阵中由相连的积水单元格(“W”)构成的池塘数量,
土地信息:农夫约翰拥有一片 的矩形土地,用字符矩阵表示,矩阵中的每个单元格代表土地的一个小块。
积水表示:如果单元格包含雨水,用 “W” 表示;不含雨水则用 “.” 表示。
池塘定义:每组相连的积水单元格集合视为一片池塘,且每个单元格与其上、下、左、右、左上、右上、左下、右下八个邻近单元格相连。
任务目标:统计字符矩阵中相连的 “W” 块的数量,即池塘的数量。
伪代码:
习题2:(城堡问题)floodfill:
分析:
一个很简单的bfs就可以解决,根据每个方格的数字判断可以扩展的方向即可
以11为例:
只有右边可以走
伪代码:
习题3(山峰和山谷)floodfill:
分析:
这是一道关于在给定地图中统计山峰和山谷数量的算法问题,可使用广度优先搜索(BFS)算法来解决,以下是详细分析:
问题分析
输入:一个 n×n 的二维网格地图,每个格子 (i, j) 都有对应的高度 w(i, j)。
输出:分别计算并输出地图中符合定义的山峰数量和山谷数量。如果所有格子高度相同,整个地图既是山峰又是山谷。
伪代码:
习题4(迷宫问题)bfs最短路:
分析:
这是一道使用搜索算法来求解迷宫最短路径的问题,常见的解决方法有广度优先搜索(BFS)算法,以下是详细分析:
初始化:创建一个与迷宫大小相同的二维数组 visited 来记录每个位置是否被访问过,初始值都为 false;创建一个队列 queue 用于存储待探索的位置;将起点 (0, 0) 标记为已访问,并加入队列;
BFS 过程:
-当队列不为空时,取出队首位置 (x, y)。
-检查当前位置是否为终点 (n, n ),如果是,则通过 parent 数组回溯得到最短路径。
-否则,按照上下左右四个方向(即 (x - 1, y)、(x + 1, y)、(x, y - 1)、(x, y + 1))探索相邻位置。
对于每个相邻位置 (nx, ny),判断其是否在迷宫范围内、是否为通路(值为 0)且未被访问过。-如果满足这些条件,则将其标记为已访问,记录其前驱节点为 (x, y),并加入队列。
利用vis,记录转移的方向,规则如下
伪代码:
习题6(武士风度的牛)特殊转移的bfs:
分析:
这道题和上一个走迷宫的题一样,只是dx和dy有所改变,另外需要记录步数,其他基本一样
伪代码:
习题7(抓住那头牛)特殊规则移动bfs:
分析:
这是一道关于在数轴上求最短路径(时间)的问题,可通过广度优先搜索(BFS)算法解决