广度优先搜索(Breadth-First Search,BFS)是一种用于遍历或搜索树或图的算法。它从起始节点开始,首先访问起始节点的所有邻接节点,然后再依次访问这些邻接节点的邻接节点,以此类推,一层一层地向外扩展,直到找到目标节点或者遍历完整个图或树。
BFS的核心思想可以概括为“全面扩散、逐层递进”。这一思想源于其处理方式:从起始节点开始,逐层扩展至更深的节点。在实现时,BFS通常使用队列(Queue)来实现,因为队列的先进先出(FIFO)特性保证了节点按照层次顺序被访问。
广度优先搜索(Breadth-First Search,BFS)是一种用于遍历或搜索树或图的算法。它从起始节点开始,逐层向外扩展,直到找到目标节点或遍历完整个图。
特性 |
BFS |
DFS |
数据结构 |
队列 |
栈 |
空间复杂度 |
O(宽) |
O(深) |
适用场景 |
最短路径 |
拓扑排序等 |
给定一个N×M的网格迷宫,其中每个格子要么是道路(用1表示),要么是障碍物(用0表示)。已知迷宫的入口位置为(x1,y1),出口位置为(x2,y2),问从入口走到出口,最少要走多少个格子。
输出从入口到出口的最少步数,如果无法到达,则输出-1。
这是一个典型的最短路径问题,可以使用BFS来解决。BFS的逐层扩展特性保证了最先到达出口的路径就是最短路径。具体步骤如下:
解题思路
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class MazeBFS {
static int[][] maze;
static boolean[][] visited;
static int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; // 四个方向
static int rows, cols;
static int startRow, startCol, endRow, endCol;
static int minSteps = -1;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
rows = scanner.nextInt();
cols = scanner.nextInt();
maze = new int[rows][cols];
visited = new boolean[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
maze[i][j] = scanner.nextInt();
}
}
startRow = scanner.nextInt() - 1; // 转换为从0开始的索引
startCol = scanner.nextInt() - 1;
endRow = scanner.nextInt() - 1;
endCol = scanner.nextInt() - 1;
bfs();
System.out.println(minSteps);
}
public static void bfs() {
Queue queue = new LinkedList<>();
queue.offer(new int[]{startRow, startCol, 0});
visited[startRow][startCol] = true;
while (!queue.isEmpty()) {
int[] current = queue.poll();
int currentRow = current[0];
int currentCol = current[1];
int steps = current[2];
if (currentRow == endRow && currentCol == endCol) {
minSteps = steps;
return;
}
for (int[] dir : dirs) {
int newRow = currentRow + dir[0];
int newCol = currentCol + dir[1];
if (newRow >= 0 && newRow < rows && newCol >= 0 && newCol < cols && maze[newRow][newCol] == 1 && !visited[newRow][newCol]) {
visited[newRow][newCol] = true;
queue.offer(new int[]{newRow, newCol, steps + 1});
}
}
}
}
}
假设输入的迷宫如下:
5 5
1 1 1 1 1
1 0 0 0 1
1 0 1 0 1
1 0 0 0 1
1 1 1 1 1
1 1 5 5
迷宫的布局如下图所示:
S表示入口,E表示出口,0表示障碍物,1表示道路。
S 1 1 1 1
1 0 0 0 1
1 0 1 0 1
1 0 0 0 1
1 1 1 1 E
BFS的搜索过程如下图所示:
首先将入口位置(1,1)入队,标记为已访问。
然后依次处理队列中的节点,按照四个方向扩展。
当搜索到出口位置(5,5)时,返回当前步数。
给定一棵二叉树,找到从根节点到叶子节点的最短路径的深度。
输入为二叉树的节点结构,可以通过递归或其他方式构建。
输出最短路径的深度。
二叉树的层序遍历可以使用BFS来实现,通过逐层遍历,找到第一个叶子节点时的深度即为最短路径的深度。具体步骤如下:
解题思路
避坑指南
import java.util.LinkedList;
import java.util.Queue;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class MinDepthBFS {
public static int minDepth(TreeNode root) {
if (root == null) return 0;
Queue queue = new LinkedList<>();
queue.offer(root);
int depth = 1;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if (node.left == null && node.right == null) {
return depth;
}
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
depth++;
}
return depth;
}
public static void main(String[] args) {
// 示例构建二叉树
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
System.out.println(minDepth(root)); // 输出2
}
}
假设输入的二叉树如下:
1
/ \
2 3
/ \
4 5
BFS的搜索过程如下图所示:
首先将根节点1入队,深度初始化为1。
处理根节点1,发现其不是叶子节点,将左右子节点2和3入队。
处理第二层的节点2和3,发现节点3是叶子节点,返回当前深度2。
掌握BFS算法不仅有助于蓝桥杯等赛事,更是提升编程能力的关键。随着全球AI竞赛进入白热化阶段 ,算法能力变得更加重要。
相关热门推荐:
本文代码已通过CSDN在线测试,如需获取完整可运行代码,请三连后在评论区留言!
读者互动: 你觉得BFS在算法竞赛中最难的部分是? A) 队列实现 B) 边界处理 C) 最短路径证明