【发布时间】:2021-09-22 17:54:35
【问题描述】:
class PriorityQueue {
constructor() {
this.values = []
}
enqueue(value, priority) {
if(this.values.length === 0) {
this.values.push({value: value, priority: priority})
return this.values;
}
this.values.push({value, priority});
this.bubbleUp(this.values);
}
bubbleUp(values) {
let childIndex = values.length-1;
let parentIndex;
parentIndex = Math.floor((childIndex-1)/2);
let childNode, parentNode, temp;
console.log(parentIndex, childIndex);
console.log(values[parentIndex].priority, values[childIndex].priority)
while ((values[childIndex].priority) < (values[parentIndex].priority)) {
childNode = values[childIndex];
parentNode = values[parentIndex];
temp = childNode;
childNode = parentNode;
parentNode = temp;
values[childIndex] = childNode;
values[parentIndex] = parentNode;
childIndex = parentIndex;
parentIndex = Math.floor((childIndex-1)/2);
}
return values;
}
}
以上是我使用 JavaScript 实现的优先级队列。
我将数据存储在一个数组中,该数组包含像这样的对象的节点
{值:“某事”,优先级:1}
当我尝试使用 enqueue 方法添加第二个节点时,while 条件中出现错误。
Uncaught TypeError: Cannot read properties of undefined (reading 'priority')
在前面的console.log语句中可以清楚地看到节点的优先级值。我无法弄清楚为什么循环条件失败并出现错误,提示我正在尝试读取未定义的属性。
任何帮助将不胜感激。
【问题讨论】:
-
你不是在第二次循环迭代中得到
parentIndex = -1吗?子索引将在某个时候最终为 0。我认为您错过了在没有更多节点时停止的条件。 -
不,我还没有出队,我只是添加节点。我可以在 while 条件之前清楚地看到控制台语句的输出。您可以复制此代码并粘贴到 jsfiddle 或浏览器中并检查。
-
您在循环之前记录,而不是在循环内部。您从
parentIndex = 0和childIndex = 1开始。下一次 WHILE 验证它是否应该继续时,parentIndex将已经是-1(Math.floor((0-1)/2)) 并且您最终以负索引引用values。那是你得到一个未定义的地方,因为values[-1] === undefined。 -
我通过用
if (parentIndex !==0)将 while 循环内的最后两行括起来来解决上述问题,谢谢
标签: javascript data-structures priority-queue