优先级队列和堆之间的区别

时间:2013-09-24 22:34:59

标签: c++ algorithm heap priority-queue

似乎优先级队列只是具有正常队列操作的堆,如insert,delete,top等。这是解释优先级队列的正确方法吗?我知道您可以以不同的方式构建优先级队列但是如果我要从堆构建优先级队列,则需要创建优先级队列类并提供构建堆和队列操作的说明,或者是否真的不需要构建班级?

我的意思是,如果我有一个构建堆的函数和函数来执行诸如insert,delete之类的操作,我是否需要将所有这些函数放在一个类中,或者我可以通过在{{ 1}}。

我想我的问题是,拥有一组函数是否等同于将它们存储在某个类中并通过类使用它们或仅使用函数本身。

以下是优先级队列实现的所有方法。这足以称之为实现,还是需要将其放在指定的优先级队列类中?

main

5 个答案:

答案 0 :(得分:85)

优先级队列是abstract datatype。它是描述特定接口和行为的简写方式,并且没有提及底层实现。

堆是data structure。它是存储数据的特定方式的名称,使某些操作非常有效。

实际上,堆是一个非常好的数据结构来实现优先级队列,因为堆数据结构有效的操作是优先级队列接口所需的操作。

答案 1 :(得分:7)

拥有一个具有所需界面的类(只需插入和弹出 - 最大?)具有它的优点。

  • 您可以稍后交换实现(例如,列表而不是堆)。
  • 读取使用队列的代码的人不需要了解堆数据结构的更难接口。
  

我想我的问题是是否有一系列功能   相当于将它们存储在某个类中并通过它们使用它们   或只是使用函数本身。

如果您只是考虑“我的程序如何表现”,那么它几乎是等效的。但它并不等同于“人类读者理解我的程序有多容易”

答案 2 :(得分:2)

术语优先级队列是指用于对其元素的优先级进行排序的一般数据结构。有多种方法可以实现这一点,例如,各种有序树结构(例如,展开树工作得相当好)以及各种堆,例如d-sheaps或Fibonacci堆。从概念上讲,是一种树结构,其中每个节点的权重不小于在该节点路由的子树中任何节点的权重。

答案 3 :(得分:2)

  

C ++标准模板库提供了make_heap,push_heap   和堆的pop_heap算法(通常实现为二进制   堆),对任意随机访问迭代器进行操作。它对待   迭代器作为对数组的引用,并使用数组到堆   转换。它还提供容器适配器priority_queue,   它将这些设施包装在类似容器的类中。但是,那里   对于减少/增加键操作没有标准支持。

priority_queue引用完全由可能对其执行的操作定义的抽象数据类型。在C ++中,STL prioroty_queue因此是序列适配器之一 - 基本容器的适配器(vector,list和deque是基本的,因为它们不能在不损失效率的情况下彼此构建),定义在<queue>标题中(实际上是<bits/stl_queue.h>)。从其定义可以看出,(如Bjarne Stroustrup所说):

  

容器适配器为容器提供受限制的接口。在   特别是,适配器不提供迭代器;他们的意图是   仅通过其专用界面使用。

我的实施prioroty_queue被描述为

/**
   *  @brief  A standard container automatically sorting its contents.
   *
   *  @ingroup sequences
   *
   *  This is not a true container, but an @e adaptor.  It holds
   *  another container, and provides a wrapper interface to that
   *  container.  The wrapper is what enforces priority-based sorting 
   *  and %queue behavior.  Very few of the standard container/sequence
   *  interface requirements are met (e.g., iterators).
   *
   *  The second template parameter defines the type of the underlying
   *  sequence/container.  It defaults to std::vector, but it can be
   *  any type that supports @c front(), @c push_back, @c pop_back,
   *  and random-access iterators, such as std::deque or an
   *  appropriate user-defined type.
   *
   *  The third template parameter supplies the means of making
   *  priority comparisons.  It defaults to @c less<value_type> but
   *  can be anything defining a strict weak ordering.
   *
   *  Members not found in "normal" containers are @c container_type,
   *  which is a typedef for the second Sequence parameter, and @c
   *  push, @c pop, and @c top, which are standard %queue operations.
   *  @note No equality/comparison operators are provided for
   *  %priority_queue.
   *  @note Sorting of the elements takes place as they are added to,
   *  and removed from, the %priority_queue using the
   *  %priority_queue's member functions.  If you access the elements
   *  by other means, and change their data such that the sorting
   *  order would be different, the %priority_queue will not re-sort
   *  the elements for you.  (How could it know to do so?)

模板:

  template<typename _Tp, typename _Sequence = vector<_Tp>,
       typename _Compare  = less<typename _Sequence::value_type> >
    class priority_queue
    {

与此相反, heap 描述了如何获取元素并将其存储在内存中。 It is a (tree based) data structure,其他是数组,哈希表,结构,联合,集合......,另外满足堆属性:所有节点都是[大于或等于]或[根据为堆定义的比较谓词,小于或等于每个子节点。

所以在我的堆头中我找不到堆容器,而是找到一组算法

  /**
   * @defgroup heap_algorithms Heap Algorithms
   * @ingroup sorting_algorithms
   */ 

像:

  • __ is_heap_until
  • __ is_heap
  • __ push_heap
  • __ adjust_heap
  • __ pop_heap
  • make_heap
  • sort_heap

所有这些(不包括__is_heap,注释为“此函数是扩展名,不是C ++标准的一部分”),描述为

   *  @ingroup heap_algorithms
   *
   *  This operation... (what it  does)

答案 4 :(得分:0)

不是真的。名称中的“优先级”源于队列中条目的优先级值,定义它们......当然:优先级。但是,有很多方法可以实现这样的PQ。