当前位置:首页 > JavaScript

js实现寻路算法

2026-03-01 17:26:49JavaScript

广度优先搜索(BFS)寻路算法

BFS通过逐层遍历相邻节点寻找最短路径,适合无权图或网格地图。

function bfsFindPath(grid, start, end) {
  const rows = grid.length;
  const cols = grid[0].length;
  const directions = [[-1,0],[1,0],[0,-1],[0,1]];
  const queue = [[start[0], start[1]]];
  const visited = Array(rows).fill().map(() => Array(cols).fill(false));
  const prev = Array(rows).fill().map(() => Array(cols).fill(null));

  visited[start[0]][start[1]] = true;

  while (queue.length) {
    const [x, y] = queue.shift();
    if (x === end[0] && y === end[1]) break;

    for (const [dx, dy] of directions) {
      const nx = x + dx, ny = y + dy;
      if (nx >=0 && nx < rows && ny >=0 && ny < cols 
          && !grid[nx][ny] && !visited[nx][ny]) {
        visited[nx][ny] = true;
        prev[nx][ny] = [x, y];
        queue.push([nx, ny]);
      }
    }
  }

  // 回溯路径
  const path = [];
  let [x, y] = end;
  while (prev[x][y]) {
    path.unshift([x, y]);
    [x, y] = prev[x][y];
  }
  return path.length ? [start, ...path] : null;
}

A* 寻路算法

A*算法结合了Dijkstra和启发式函数,适合带权图或复杂地形。

class PriorityQueue {
  constructor() {
    this.elements = [];
  }
  enqueue(element, priority) {
    this.elements.push({element, priority});
    this.elements.sort((a,b) => a.priority - b.priority);
  }
  dequeue() {
    return this.elements.shift().element;
  }
  isEmpty() {
    return !this.elements.length;
  }
}

function aStarFindPath(grid, start, end) {
  const rows = grid.length;
  const cols = grid[0].length;
  const directions = [[-1,0],[1,0],[0,-1],[0,1]];
  const heuristic = (x,y) => Math.abs(x-end[0]) + Math.abs(y-end[1]);

  const openSet = new PriorityQueue();
  openSet.enqueue([start[0], start[1]], 0);

  const gScore = Array(rows).fill().map(() => Array(cols).fill(Infinity));
  gScore[start[0]][start[1]] = 0;

  const fScore = Array(rows).fill().map(() => Array(cols).fill(Infinity));
  fScore[start[0]][start[1]] = heuristic(start[0], start[1]);

  const cameFrom = Array(rows).fill().map(() => Array(cols).fill(null));

  while (!openSet.isEmpty()) {
    const [x, y] = openSet.dequeue();
    if (x === end[0] && y === end[1]) {
      // 回溯路径
      const path = [[x, y]];
      let current = cameFrom[x][y];
      while (current) {
        path.unshift(current);
        current = cameFrom[current[0]][current[1]];
      }
      return path;
    }

    for (const [dx, dy] of directions) {
      const nx = x + dx, ny = y + dy;
      if (nx >=0 && nx < rows && ny >=0 && ny < cols && !grid[nx][ny]) {
        const tentativeG = gScore[x][y] + 1;
        if (tentativeG < gScore[nx][ny]) {
          cameFrom[nx][ny] = [x, y];
          gScore[nx][ny] = tentativeG;
          fScore[nx][ny] = tentativeG + heuristic(nx, ny);
          if (!openSet.elements.some(e => e.element[0]===nx && e.element[1]===ny)) {
            openSet.enqueue([nx, ny], fScore[nx][ny]);
          }
        }
      }
    }
  }
  return null; // 未找到路径
}

使用示例

// 0表示可通行,1表示障碍物
const grid = [
  [0,0,0,0,0],
  [0,1,1,1,0],
  [0,1,0,0,0],
  [0,1,0,1,0],
  [0,0,0,1,0]
];

const start = [0,0];
const end = [4,4];

console.log(bfsFindPath(grid, start, end));
console.log(aStarFindPath(grid, start, end));

实现要点

BFS实现关键

  • 使用队列管理待访问节点
  • 维护visited数组避免重复访问
  • 通过prev数组记录路径来源
  • 路径回溯从终点反推

*A实现关键

  • 优先队列管理开放集
  • gScore记录实际移动成本
  • fScore = gScore + 启发式估值
  • 曼哈顿距离作为启发函数
  • 动态更新节点评分

两种算法中,A通常效率更高,但BFS保证找到最短路径。实际应用中可根据场景需求选择,复杂地形推荐A算法,简单网格可用BFS。

js实现寻路算法

标签: 算法js
分享给朋友:

相关文章

js实现图片轮播

js实现图片轮播

实现基础图片轮播 使用HTML、CSS和JavaScript创建一个简单的图片轮播。HTML部分定义轮播容器和图片,CSS设置样式和动画效果,JavaScript处理轮播逻辑。 <div c…

js 实现倒计时

js 实现倒计时

实现倒计时的基本方法 使用 JavaScript 实现倒计时可以通过 setInterval 或 setTimeout 结合日期计算来完成。以下是两种常见实现方式。 使用 setInterval…

原生js实现轮播图

原生js实现轮播图

基本结构搭建 HTML部分需要包含轮播图容器、图片列表及导航按钮。结构示例如下: <div class="slider-container"> <div class="slid…

js实现类

js实现类

JavaScript 实现类的几种方式 JavaScript 是一种基于原型的语言,但在 ES6 之后引入了 class 语法糖,使得实现类更加直观。以下是几种常见的实现方式: 使用构造函数 传统的…

js实现论坛

js实现论坛

实现论坛的基本功能 使用JavaScript实现一个论坛需要结合前端和后端技术。前端可以使用React、Vue或Angular等框架,后端可以选择Node.js配合Express或Koa框架。数据库可…

js实现图表

js实现图表

在JavaScript中实现图表通常使用流行的图表库,以下是几种常见的方法和工具: 使用Chart.js Chart.js是一个简单灵活的库,适合快速生成响应式图表。安装方式包括CDN引入或npm安…