bfs天然适合求解无权图最短路径,迷宫建模为网格图,用队列存储坐标及步数,visited数组防重复,出队时判终点,四向扩展并更新前驱可还原路径。

广度优先搜索(BFS)天然适合求解无权图中的最短路径问题,迷宫可建模为网格图,每个格子是节点,相邻可通行格子间有边,BFS 一层层向外扩展,第一次到达终点时的步数就是最短路径长度。
迷宫建模与数据结构准备
把二维字符数组或布尔矩阵作为地图:'0' 或 true 表示可通过,'1' 或 false 表示墙。起点 (sx, sy)、终点 (ex, ey) 明确后,用 Queue 存储待访问坐标(常用 int[] 或自定义 Point 类),再用 boolean[][] visited 数组避免重复访问。建议直接用 int[] {x, y, step} 入队,把步数记在状态里,比额外维护距离数组更直观。
- 用 LinkedList 或 ArrayDeque 实现队列,后者性能略优
- 四个方向偏移量可预定义为 int[][] dirs = {{-1,0},{1,0},{0,-1},{0,1}};遍历时检查新坐标是否越界、是否可走、是否已访问
- 初始将起点入队,visited[sx][sy] = true,step 设为 1(若起点算第 1 步)或 0(按移动次数计)——统一标准即可
BFS 主循环与终止条件
每次从队首取一个节点,检查是否到达终点:若 x == ex && y == ey,直接返回当前 step。否则遍历四个方向,对每个合法邻居,标记 visited 并入队,step + 1。若队列为空仍未找到终点,说明不可达,返回 -1。
- 不要在入队时判断终点——可能漏掉起点即终点的情况;应在出队时判断
- step 随每个新节点递增,不是全局变量,而是随状态携带,确保每层扩展对应统一距离
- Java 中推荐用 while (!queue.isEmpty()) + for (int i = queue.size(); i > 0; i--) 模拟“层”概念,便于统计层数,但非必须
还原具体路径(不止是长度)
如果题目要求输出路径(如坐标列表),需记录每个节点的前驱。可用 int[][] prev 存储上一坐标的 x 和 y(例如 prev[x][y] = new int[]{px, py}),或用 Map
- prev 数组初始化为 null 或 {-1,-1},起点 prev[sx][sy] 设为自身或特殊标记
- 入队时同时更新 prev[nx][ny] = {x, y},注意只在首次访问时设置
- 路径重建用 ArrayList 循环 add,最后 Collections.reverse() 即可
常见坑与优化点
边界检查顺序很重要:先判越界,再判是否可走,最后判是否已访问——避免因数组越界抛异常。多组测试时记得重置 visited 数组。若迷宫极大且内存敏感,可考虑用 Set
- 起点或终点是墙?提前校验,直接返回 -1
- Java 中 new int[]{x,y} 创建数组开销小,但高频场景下复用对象池意义不大,可读性优先
- 不必要用 PriorityQueue——BFS 本身已保证首次到达即最短,堆会退化为 Dijkstra,反而慢
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











