在C ++中有效地管理数组二进制堆的句柄?

时间:2016-09-08 04:44:25

标签: c++ heap binary-heap

有没有办法有效地跟踪数组二进制堆中的句柄?

由于传统的二进制堆中没有内置快速查找,用户需要一个' handle_type'对于堆中任意元素的删除或reduce_key

您无法在数组中使用指针或索引,因为堆操作会移动元素的位置。我不能像传统的堆实现那样只考虑使用类似堆栈的结构的简单解决方案。否则,我必须使用' new / delete'这感觉效率低下。

我不想过于沉迷于预成熟优化,但我希望这是我的标准实用程序库的一部分,所以我想付出一点努力了解这类事情的最佳实践。

也许只是一个使用' new / delete'的简单实现是去这里的方式。但是,如果可以的话,我想先得到比我更聪明的人的建议。

C ++标准库中的优先级队列实现似乎完全不需要支持' decrease_key'操作。我一直在翻阅CLRS,他们提到了这个问题,但并没有真正讨论它:

  除了注意到......这些句柄之外,我们不会在这里追求它们   确实需要正确维护。

这里有一个简单的方法吗?我可以俯视吗? "严肃的"库需要一个需要“减少”键的通用数组堆时才会这样做。操作吗

1 个答案:

答案 0 :(得分:2)

  

有没有办法有效地跟踪数组二叉树中的句柄?

假设可能(但不是很漂亮)。在内部,数据结构不是存储元素数组,而是将指针数组(或智能指针)存储到包含一对索引和元素的结构中。

  1. 当元素首次插入数组中的位置 i 时,数据结构会将此结构的索引初始化为 i

  2. 当数据结构在数组周围移动元素时,它应修改索引以反映新位置。

  3. push的结果可以是指向此结构的指针(可能包含在不透明的类中)。为了访问特定元素(例如,对于decrease_key),您将使用此返回值调用堆的某个方法。然后堆将

    1. 知道阵列的地址(毕竟它是其成员)
    2. 通过刚刚发送的结构知道数组中的索引。
    3. 例如,它可以实现decrease_key

      然而,可能有更好(并且不那么繁琐)的解决方案。请注意,上述解决方案不会改变数组堆的渐近复杂度,但常量会更糟。相反,如果你看一下这个summary of heap running times,你会发现二进制堆对decrease_key操作并没有很好的表现。如果您需要,您最好使用Fibonnacci堆(或其他一些数据结构)。这导致了您的最后一个问题

        

      "严肃的"库需要一个需要“减少”键的通用数组堆时才会这样做。操作

      boost::heap等库通常确实实现了更适合更高级操作的其他数据结构(例如decrease_key)。这些数据结构自然是基于节点的,并且自然地支持返回值,这些返回值不像数组中那样容易失效。