优先级队列 - 二进制堆

时间:2012-04-15 01:20:02

标签: c++ arrays map priority-queue binary-heap

我正在尝试将优先级队列实现为已排序数组支持的最小二进制堆。我试图让update_key函数在对数时间运行,但为了做到这一点,我必须知道数组中项目的位置。无论如何不使用地图这样做?如果是这样,怎么样?谢谢

3 个答案:

答案 0 :(得分:2)

如果您真的希望能够更改任意元素的键,则堆不是数据结构的最佳选择。它给你的是:

的组合
  1. 紧凑表示(没有指针,只是一个数组和一个隐式 索引方案)
  2. 对数插入,重新平衡
  3. 对数去除最小(最大)元素。
  4. O(1)访问最小(最大)元素的值。 -
  5. 1.的另一个好处是缺少指针意味着您对malloc/freenew/delete)的呼叫要少得多。 地图(在标准库中表示为平衡二叉树)为您提供其中的两个,添加

    1. 任意键上的对数find()
    2. 因此,虽然您可以将另一个数据结构附加到堆中,将指针存储在堆中,然后通过指针使比较运算符取消引用,但您很快就会发现自己只需使用{的时间和空间的复杂性首先是{1}}。

答案 1 :(得分:0)

您的查找键功能应在log(n)时间内运行。您的更新(更改密钥)应该是恒定的时间。你的删除功能应该在log(n)时间内运行。你的插入函数应该是log(n)时间。

如果这些假设属实,请尝试以下方法: 1)在堆中找到你的项目(IE:二进制搜索,因为它是一个排序的数组)。 2)更新你的密钥(你只是改变一个值,恒定的时间) 3)从堆日志(n)中删除该项目以重新加密 4)将您的项目插入堆日志(n)。

所以,你有log(n)+ 1 + log(n)+ log(n),它减少到log(n)。

注意:这是分摊的,因为如果你必须重新分配你的数组等......这会增加开销。但无论如何你不应该经常这样做。

答案 2 :(得分:0)

这是数组支持堆的权衡:你获得了极好的内存使用(良好的局部性和最小的开销),但是你会忘记元素。要解决这个问题,你必须补充一些开销。

一种解决方案就是这样。堆包含C*类型的对象。 C是一个int成员heap_index的类,它是堆数组中对象的索引。每当您在堆数组中移动元素时,您都必须更新其heap_index以将其设置为新索引。

然后

Update_key(以及删除任意元素)是log(n)时间,因为它需要花费不变的时间来查找元素(通过heap_index),并记录log(n)时间以将其冒泡到正确的位置。