当前位置:首页 > 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、CSS和JavaScript创建一个简单的图片轮播。HTML部分定义轮播容器和图片,CSS设置样式和动画效果,JavaScript处理轮播逻辑。 <div cl…

js实现打印

js实现打印

使用window.print()方法实现打印 在JavaScript中,可以通过调用window.print()方法直接触发浏览器的打印功能。这会打开系统的打印对话框,用户可以选择打印机和设置打印选项…

js实现验证

js实现验证

验证表单输入 使用JavaScript验证表单输入是常见的需求。可以通过监听表单提交事件,检查输入字段是否符合要求。 document.getElementById('myForm').addEve…

js 实现分页

js 实现分页

实现分页的基本逻辑 分页功能通常需要后端返回数据总量或总页数,前端根据当前页码和每页条数截取对应数据。以下是一个基于JavaScript的简单分页实现方案: 前端分页实现 假设已有从后端获取的完整数…

js实现拷贝

js实现拷贝

实现文本拷贝 使用 document.execCommand 方法(已废弃但兼容性较好): function copyText(text) { const textarea = document…

js 实现拖拽

js 实现拖拽

实现拖拽的基本步骤 在JavaScript中实现拖拽功能需要监听几个关键事件:mousedown、mousemove和mouseup。以下是实现的基本逻辑。 监听目标元素的mousedown事件,记…