实现优先级队列和堆

implementing priority queues and heaps

我正在尝试根据 "Introduction to Algorithms, Third Edition" 中的描述使用二进制最小堆实现最小优先级队列并有几个问题。

书上说我们经常需要在每个堆元素中存储一个应用对象的句柄(指针或整数),还需要在每个应用对象中存储一个堆元素的句柄(数组索引) .

1) 堆实现通常看起来像这样吗?

template <class KeyType, class ObjectType>
struct HeapElement
{
    KeyType key;
    ObjectType* pObject;
};


template <class KeyType, class ObjectType>
class MinHeap
{
  // ...
private:
  std::vector< HeapElement<KeyType, ObjectType> > data;
};

然后 ObjectType class 也会存储 heapIndex:

class Foo
{
 // ...
  int heapIndex;
};

2) 最小优先级队列和二进制最小堆通常作为单个实现 class 还是最小优先级队列通常作为其自身实现 class 与私有堆 class 成员?

class MinPriorityQueue
{
  // ...
private:
  MinHeap minHeap;
};

我问的原因是因为如果您查看 ExtractMin() 之类的实现,它需要您操作堆数据:

int min = data[0]; // data: private heap data member
heapSize--; // heapSize: private heap data member
MinHeapify(0); // MinHeapify: private heap member function

所以也许最小优先级队列 class 应该充当包装器 class?

T MinPriorityQueue::ExtractMin()
{
  return minHeap.ExtractMin();
}

在这种情况下,二进制最小堆 class 可能会实现 Min()ExtractMin()DecreaseKey()Insert() 并包含两者的功能二进制最小堆和最小优先级队列。那么根本不需要 MinPriorityQueue class。

问题的范围是实施 heaps/priority 面试队列。对此有什么想法吗?

1) 通常你不想仅仅因为你想把它们堆成一堆就必须修改你的值类型。你会让你的堆像这样:

template <class KeyType, class ObjectType>
struct HeapElement
{
    KeyType key;
    size_t heapIndex;
    ObjectType* pObject;
};


template <class KeyType, class ObjectType>
class MinHeap
{
  // ...
private:
  //this is just to allocate the data.  Elements in here don't move
  std::vector< HeapElement<KeyType, ObjectType> > data;

  //this is the heap.  Elements are indexes into data vector
  std::vector<size_t> heapArray;
};

然后,在整个 Dijkstra 算法的实现过程中,您使用数据向量中的索引来引用对象,并且您可以使用 data[itemIndex].heapIndex.

获取每个项目的堆索引

但请在此处查看我的回答: ...我通常在不使用 decrease_key 操作的情况下 实施 Dijkstra 算法。

2) 我真的看不出有什么理由要创建一个与优先级队列实现分开的堆 class。我实际上会调用 class 你需要一个 "Heap",但不是优先级队列,因为优先级队列接口通常不期望键与对象分开。

应该在矢量上使用std::make_heapstd::push_heapstd::pop_heap