当前位置:首页 > 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实现关键

js实现寻路算法

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

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

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

相关文章

js实现轮播

js实现轮播

实现基础轮播效果 使用HTML结构创建轮播容器和图片元素: <div class="carousel"> <div class="carousel-inner">…

jquery.js

jquery.js

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,用于简化 HTML 文档遍历、事件处理、动画设计和 Ajax 交互。它的设计宗旨是“Write Less, Do Mor…

js轮播图实现原理

js轮播图实现原理

轮播图的基本原理 轮播图通过动态切换显示的内容(图片、文本等)实现视觉上的滑动效果。核心原理是利用CSS和JavaScript控制元素的显示与隐藏,或通过变换位置实现滑动动画。 实现方法一:…

jquery js

jquery js

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画和 Ajax 交互。它兼容多种浏览器,提供易于使用的 API,使开发者能够更高…

js实现图

js实现图

JavaScript 实现图的常用方法 在 JavaScript 中,图(Graph)可以通过多种方式实现,常见的包括邻接表(Adjacency List)和邻接矩阵(Adjacency Matrix…

js实现下拉刷新

js实现下拉刷新

监听触摸事件 通过监听 touchstart、touchmove 和 touchend 事件来检测用户下拉手势。记录触摸起始位置和移动距离。 let startY = 0; let curr…