简体   繁体   English

实现优先级队列和堆

[英]implementing priority queues and heaps

I am trying to implement a min priority queue using a binary min heap based on the description from "Introduction to Algorithms, Third Edition" and have a couple of questions. 我正在尝试根据“算法简介,第三版”中的描述使用二进制最小堆来实现最小优先级队列,并且有几个问题。

The book says that we often need to store a handle (pointer or integer) to the application object in each heap element and that we also need to store a handle (array index) to the heap element in each application object. 这本书说,我们经常需要在每个堆元素中存储到应用程序对象的句柄(指针或整数),并且还需要在每个应用程序对象中存储到堆元素的句柄(数组索引)。

1) Would the heap implementation typically look something like this then? 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;
};

And then the ObjectType class would also store the heapIndex: 然后,ObjectType类还将存储heapIndex:

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

2) Is the min priority queue and binary min heap typically implemented as a single class or is the min priority queue usually implemented as its own class with a private heap class member? 2)最小优先级队列和二进制最小堆通常是作为单个类实现还是最小优先级队列通常与私有堆类成员一起作为其自己的类实现?

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

The reason I ask is because if you look at the implementation for something like ExtractMin() , it requires that you manipulate the heap data: 我问的原因是因为如果您查看实现中的ExtractMin() ,则需要您操纵堆数据:

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

So maybe the min priority queue class should act as a wrapper class? 那么,最小优先级队列类应该充当包装器类吗?

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

In that case, the binary min heap class might implement Min() , ExtractMin() , DecreaseKey() , and Insert() and contain the functionality for both a binary min heap and min priority queue. 在这种情况下,二进制最小堆类可能实现Min()ExtractMin()DecreaseKey()Insert()并且包含二进制最小堆和最小优先级队列的功能。 Then there would be no need for a MinPriorityQueue class at all. 这样就根本不需要MinPriorityQueue类。

The scope of the question is implementing heaps/priority queues for job interviews. 问题的范围是为工作面试实现堆/优先级队列。 Any thoughts on this? 有什么想法吗?

1) Usually you don't want to have to modify your value types just because you want to make a heap of them. 1)通常,您不必仅因为要堆积大量的值而就不必修改值类型。 You'd make your heap something like this: 您将使堆如下所示:

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;
};

Then, throughout the implementation of Dijkstra's algorithm you use indexes into the data vector to refer to objects, and you can get each item's heap index with data[itemIndex].heapIndex . 然后,在Dijkstra算法的整个实现过程中,您都使用数据向量中的索引来引用对象,并且可以使用data[itemIndex].heapIndex获得每个项目的堆索引。

BUT see my answer over here: Prim's Algorithm: How to get index of key on which DECREASE_KEY operation is to be performed? 但是在这里看到我的答案: Prim的算法:如何获取要在其上执行DECREASE_KEY操作的键的索引? ... I usually implement Dijkstra's algorithm without a decrease_key operation. ...我通常不执行reduce_key操作即可实现Dijkstra的算法。

2) I don't really see any reason to make a heap class that is separate from the priority queue implementation. 2)我真的看不出有什么理由要使堆类与优先级队列实现分开。 I would actually call the class you need a "Heap", though, not a priority queue, since priority queue interfaces don't usually expect the keys to be separate from the objects. 我实际上将您需要的类称为“堆”,而不是优先级队列,因为优先级队列接口通常不希望键与对象分离。

You should use std::make_heap , std::push_heap and std::pop_heap on a vector. 应该在向量上使用std::make_heapstd::push_heapstd::pop_heap

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM