javaScript——BFS结合队列求迷宫最短路径

这里推荐先去看下B站这个老师讲的BFS迷宫问题,只用看前五分钟就能懂用BFS+队列实现的原理。[POJ] 3984 迷宫问题 BFS_哔哩哔哩_bilibili

问题描述:由m*n的矩阵构成了一个迷宫, 矩阵中为1的元素表示障碍物,不能走,为0表示可以走。同时,可以你可以竖着或横着走都行,也就是四个方向都可以。问:从起点到终点的最短路径是多少,并输出最短路径上的路径信息。

 思路:采用广度优先搜索的方式,尝试让某个点朝四个方向各走一步,如果都能走通,将这些路径和步长入队。每次都对队列的元素尝试往前走一步,最早找到终点的路径就是要求的最短路径。我们定义的方向是下、上、右、左。假设由两个点分别向下、向右走一步都到了终点,并且两者的step相等,那么,先遍历的也就是向下的这个路径作为目标输出。即使路径长度都一样,只要一个即可。

 

 广度遍历不需要回溯:开始时用队列存储第一个为遍历的节点。从第一个点开始,将它shift出去,然后尝试向四周走一步,如果走的通,将那个节点和路径信息入队,依次遍历所有方向。

下次遍历时,队列里是步长为1的准备往下一步的节点了。跟之前一样,挨个shift出去,然后你就尝试四周走吧。。。直到已遍历到end节点结束。

大白话思想:从根节点出发,每次只走一步(四个方向都考虑一下),或者阻塞了走不了;走不了也shift出去了,下次不带他继续走了。每次都带着可以走的节点继续往前走。最先走到终点的节点就是循环结束。如果找不到,返回-1。

function shortestPath(maze, start, end) {
  const rows = maze.length;
  const cols = maze[0].length;
  //定义方向
  const directions = [
    [0, 1], //向下走一步,
    [0, -1], //向上走一步
    [1, 0], //向右走一步
    [-1, 0], //向左走一步
  ];
  const visited = Array.from(Array(rows), () => Array(cols).fill(false));
  const queue = [[start, 0, []]];
  while (queue.length > 0) {
    const [[X, Y], steps, path] = queue.shift();
    if (X === end[0] && Y === end[1]) {
      return [steps, path.concat([[X, Y]])];
    }
    for (let dir of directions) {
      const [dx, dy] = dir;
      const newX = X + dx;
      const newY = Y + dy;
      if (
        newX >= 0 &&
        newX < rows &&
        newY >= 0 &&
        newY < cols &&
        maze[newX][newY] == 0 &&
        !visited[newX][newY]
      ) {
        visited[newX][newY] = true;
        queue.push([[newX, newY], steps + 1, path.concat([[X, Y]])]);
      }
    }
  }
  return [-1, []];
}
// 示例迷宫
const maze = [
  [0, 1, 0, 0, 0],
  [0, 0, 0, 1, 0],
  [1, 1, 0, 1, 0],
  [1, 1, 0, 0, 0],
  [0, 0, 0, 0, 0],
];

const start = [0, 0]; // 起点坐标
const end = [4, 4]; // 终点坐标

const [steps, path] = shortestPath(maze, start, end); // 调用函数计算最短路径
if (steps !== -1) {
  console.log(`最短步数为:${steps}`); // 输出最短步数
  console.log("最短路径为:" + "[" + path.join("]->[") + "]"); // 输出最短路径
} else {
  console.log("未找到路径"); // 输出未找到路径的提示
}

 这里用二维数组存储节点已访问的状态。能不能走由四个条件判断:

newX和newY下标必须合理;maze对应位置不能有障碍,当前节点未访问

queue存储的是未遍历四个方向的当前节点。数组中每项存储的是当前遍历的节点座标,走到该节点的步长,节点携带的路径数组。

熟悉js的结构赋值,减少新增变量

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三月的一天

你的鼓励将是我前进的动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值