在我的二进制堆/优先级队列实现中实现删除时遇到问题

Posted

技术标签:

【中文标题】在我的二进制堆/优先级队列实现中实现删除时遇到问题【英文标题】:Having issues implementing remove within my Binary Heap/Priority Queue implementation 【发布时间】:2020-07-19 14:49:09 【问题描述】:

我正在尝试为我的二进制堆实现实现一个删除方法。

class Node 
  constructor(priority) 
    this.priority = priority;
  


class PriorityQueue 
  constructor() 
    this.heap = [null];
  

remove() 

  const toRemove = this.heap[1];
  this.heap[1] = this.heap.pop();  
  let currentIdx = 1;
  let [left, right] = [2*currentIdx, 2*currentIdx + 1]; 
  let currentChildIdx = this.heap[right] && this.heap[right].priority >= this.heap[left].priority ? right : left; //Assess which child node has higher priority

  while (this.heap[currentChildIdx] && this.heap[currentIdx].priority <= this.heap[currentChildIdx].priority)  
    let currentNode = this.heap[currentIdx]
    let currentChildNode = this.heap[currentChildIdx];
    this.heap[currentChildIdx] = currentNode;
    this.heap[currentIdx] = currentChildNode;
    currentIdx = this.heap.indexOf(currentNode);
  
  return toRemove;




但是,我不确定在运行 while 循环时如何正确更新 currentIdx 和 currentChildIdx 的值。事实上,当我尝试更新 currentIdx 的值时,代码似乎停止工作

currentIdx = this.heap.indexOf(currentNode);

关于我做错了什么的任何提示?

完整代码在这里:https://repl.it/@Stylebender/Binary-Heap-Naive

【问题讨论】:

【参考方案1】:

在循环中,一旦你交换了currentIdxcurrentChildIdx 的值,那么你应该分配currentIdx = currentChildIdx

而一旦你改变currentIdx,你需要重新计算左右子索引和一个新的currentChildIdx

基本思路是:

while currentIdx < heap_length
    currentChildIdx = index of largest child
    if (heap[currentIdx] >= heap[currentChildIdx])
        break; // node is now in the right place
    swap(heapCurrentIdx, heap[currentChildIdx)
    currentIdx = currentChildIdx

我的建议是您构建该基本结构,然后在调试器中单步执行它以确保它按预期工作。

【讨论】:

以上是关于在我的二进制堆/优先级队列实现中实现删除时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中实现优先级队列?

如何在实现为二进制堆的优先级队列中保留相同优先级元素的顺序?

什么是堆排序和优先队列? [关闭]

为啥在c++中实现基于类的优先级队列时需要重载operator<?

分段错误:在 C 中实现优先级队列

为什么优先级队列是使用堆实现的,当我们可以更有效地使用向量实现它时