【问题标题】:Priority Queue in JavaScript, I am not able to add more than one nodeJavaScript 中的优先级队列,我无法添加多个节点
【发布时间】: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 = 0childIndex = 1 开始。下一次 WHILE 验证它是否应该继续时,parentIndex 将已经是 -1 (Math.floor((0-1)/2)) 并且您最终以负索引引用 values。那是你得到一个未定义的地方,因为values[-1] === undefined
  • 我通过用 if (parentIndex !==0) 将 while 循环内的最后两行括起来来解决上述问题,谢谢

标签: javascript data-structures priority-queue


【解决方案1】:

检查一下,

class Node {
    constructor(data, priority) {
      this.data = data;
      this.priority = priority;
    }
  }

class PQ {
  constructor() {
    //Initialing the array heap and adding a dummy element at index 0
    this.heap = [];
  }

  getMin() {
    //Accessing the min element at index 1 in the heap array
    return this.heap[0];
  }

  enqueue(data, priority) {
    let newNode = new Node(data, priority);
    this.heap.push(newNode);

    let currentIndex = this.heap.length - 1;
    let parentIndex = Math.round(currentIndex / 2) - 1;

    while (
      currentIndex > 0 &&
      this.heap[parentIndex].priority > this.heap[currentIndex].priority
    ) {
      [this.heap[parentIndex], this.heap[currentIndex]] = [
        this.heap[currentIndex],
        this.heap[parentIndex],
      ];

      currentIndex = parentIndex;
    }
  }

  dequeue() {
    //Smallest element is at the index 1 in the heap array
    let smallest = this.heap[0];

    if (this.heap.length === 1) {
      //If there are only two elements in the array, we directly splice out the first element
      this.heap.splice(0, 1);
    }

    //When there are more than two elements in the array, we put the right most element at the
    //first position and start comparing nodes with the child nodes
    if (this.heap.length >= 2) {
      this.heap[0] = this.heap[this.heap.length - 1];
      this.heap.splice(this.heap.length - 1);

      if (this.heap.length === 2) {
        if (this.heap[0].priority > this.heap[1].priority) {
          [this.heap[0], this.heap[1]] = [this.heap[1], this.heap[0]];
        }
        return smallest;
      }

      let current = 0;
      let leftChildIndex = current * 2 + 1;
      let rightChildIndex = current * 2 + 2;

      while (
        this.heap[leftChildIndex] &&
        this.heap[rightChildIndex] &&
        (this.heap[current].priority > this.heap[leftChildIndex].priority ||
          this.heap[current].priority > this.heap[rightChildIndex].priority)
      ) {
        if (this.heap[leftChildIndex].priority < this.heap[rightChildIndex].priority) {
          [this.heap[current], this.heap[leftChildIndex]] = [
            this.heap[leftChildIndex],
            this.heap[current],
          ];
          current = leftChildIndex;
        } else {
          [this.heap[current], this.heap[rightChildIndex]] = [
            this.heap[rightChildIndex],
            this.heap[current]
          ];
          current = rightChildIndex;
        }

        leftChildIndex = current * 2 + 1;
        rightChildIndex = current * 2 + 2;
      }
    }

    return smallest;
  }
}

const pq = new PQ();
pq.enqueue(3, 2);
pq.enqueue(4, 5);
pq.enqueue(31, 1);
pq.enqueue(6, 3);
console.log(pq.heap);
console.log(pq.dequeue());
console.log(pq.dequeue());
console.log(pq.dequeue());
console.log(pq.dequeue());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 2015-03-21
    • 2013-09-20
    • 2023-04-02
    相关资源
    最近更新 更多