C++ 优先级队列-二进制堆

C++ 优先级队列-二进制堆,c++,arrays,map,priority-queue,binary-heap,C++,Arrays,Map,Priority Queue,Binary Heap,我正在尝试将优先级队列实现为排序数组支持的最小二进制堆。我试图让update_key函数以对数时间运行,但要做到这一点,我必须知道该项在数组中的位置。不使用地图也可以这样做吗?如果是,怎么做?谢谢您的查找键功能应该在日志(n)时间内运行。您的更新(更改密钥)应该是固定时间。删除函数应在日志(n)时间内运行。您的插入函数应该是log(n)time 如果这些假设为真,请尝试以下方法: 1) 在堆中查找项目(即:二进制搜索,因为它是一个排序数组)。 2) 更新密钥(您只需更改一个值,恒定时间) 3)

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

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

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

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


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

这就是基于数组的堆的折衷方案:您可以获得出色的内存使用(良好的局部性和最小的开销),但会丢失对元素的跟踪。要解决这个问题,您必须增加一些开销

一个解决办法就是这样。堆包含
C*
类型的对象。C是一个具有
int
成员
heap\u index
的类,它是堆数组中对象的索引。每当在堆数组中移动元素时,都必须更新其
heap\u索引
,以将其设置为新索引


更新密钥(以及删除任意元素)是log(n)时间,因为查找元素(通过
堆索引
)需要固定的时间,而将其冒泡到正确的位置需要log(n)时间。

如果您真的想更改任意元素的密钥,堆不是数据结构的最佳选择。它提供给您的是以下各项的组合:

  • 紧凑表示(没有指针,只有数组和隐式 索引方案)
  • 对数插入,再平衡
  • 最小(最大)元素的对数删除
  • O(1)获取最小(最大)元素的值- 1的附带利益。缺少指针意味着您对
    malloc/free
    new/delete
    )的调用大大减少。 一个映射(在标准库中表示为一个平衡二叉树)提供了其中两个,并添加了

  • 任何键上的对数
    find()

    因此,虽然可以将另一个数据结构附加到堆中,在堆中存储指针,然后通过指针使比较运算符取消引用,你很快就会发现你自己在时间和空间上都很复杂,仅仅使用一个
    map

    什么是update\u key函数?更新元素键的函数?因为二进制堆包含一个键,元素pairI不认为他指的是排序数组。典型的二进制堆实现将元素保留在数组中,但只要求heap属性为true。我认为,保持所有元素的排序并保持插入和删除元素的O(log(n))复杂性是不可能的,这是有意义的。假设一个使用了真正的堆结构,堆的根节点只需要比两个子节点更好(在排序方面),那么每个子节点都可以被视为另一个堆的根节点,这是递归的)。我不知道为什么昨晚我没有想到这件事。谢谢你的澄清。