You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript实现PriorityQueue时无法添加多个节点的报错排查

问题根因

错误触发的核心原因是bubbleUp方法的while循环缺失边界校验:当子节点上浮到数组的根节点位置(索引为0)时,继续计算父节点索引会得到Math.floor((0-1)/2) = -1,此时访问values[-1].priority就会抛出「读取undefined属性priority」的错误。
你之前的console.log能够正常打印,是因为第一次进入循环前,父节点索引为0、子节点索引为1(第二个元素的索引),两个节点均存在,所以打印正常。当第二个节点的优先级小于根节点优先级时,会进入循环完成交换,交换后子节点索引变为0,再次计算父节点索引为-1,此时执行while条件判断就会触发错误。

修复方案

在while循环的判断条件中增加父节点索引合法性校验parentIndex >= 0即可解决问题,同时可以优化冗余代码,修复后的完整代码如下:

class PriorityQueue {
  constructor() {
    this.values = []
  }
  enqueue(value, priority) {
    // 可去掉空数组的特殊判断,bubbleUp逻辑对空数组push后的场景也兼容
    this.values.push({value, priority});
    this.bubbleUp(this.values); 
    return this.values;
  }

  bubbleUp(values) {
    let childIndex = values.length - 1;
    let parentIndex = Math.floor((childIndex - 1) / 2); 
    // 新增parentIndex >= 0的边界校验
    while (parentIndex >= 0 && values[childIndex].priority < values[parentIndex].priority) {
      // 交换逻辑可以用数组解构简化,无需临时变量
      [values[childIndex], values[parentIndex]] = [values[parentIndex], values[childIndex]];
      childIndex = parentIndex;
      parentIndex = Math.floor((childIndex - 1) / 2);
    }
    return values;
  }
}
验证方法

你可以用以下测试用例验证修复效果:

const pq = new PriorityQueue();
pq.enqueue('任务1', 2);
pq.enqueue('任务2', 1); // 之前触发错误的场景,修复后可正常执行
console.log(pq.values); // 输出符合最小堆规则的优先级队列结构

内容的提问来源于stack exchange,提问作者ShashankAC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 16:30:01