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

Efficiently manage handle for an array binary heap in C++?

本文关键字:二进制 句柄 数组 管理 c++ 有效地      更新时间:2023-10-16

是否有一种方法可以有效地跟踪数组二进制堆中的句柄?

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

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

我不想太沉迷于早熟的优化,但我希望这是我的标准工具库的一部分,所以我想花一点精力去了解什么是被认为是这类事情的最佳实践。

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

c++标准库中的优先级队列实现似乎完全避开了这个问题,只是简单地不支持' elime_key '操作。我一直在浏览CLRS,他们提到了这个问题,但没有真正讨论它:

我们在这里不再追究它们,只是注意到……这些句柄需要正确保养

这里有一个简单的方法我忽略了吗?当"严肃"的库需要一个通用的数组堆,需要一个'减少键'操作时,他们会做什么?

是否有一种方法可以有效地跟踪数组二叉树中的句柄?

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

  1. 当一个元素第一次插入到数组i位置时,数据结构将初始化该结构体的索引为i

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

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

  1. 知道数组的地址(毕竟它是它的成员)
  2. 知道数组内的索引,通过你刚刚发送给它的结构体。
例如,

它可以因此实现decrease_key


然而,可能有更好(也不那么麻烦)的解决方案。注意,上面的解决方案不会改变数组堆的渐近复杂性,但常量会更糟。相反,如果您查看堆运行时间的摘要,您可以看到二进制堆对于decrease_key操作并没有真正的良好性能。如果需要的话,最好使用斐波那契堆(或其他数据结构)。这就引出了最后一个问题

当"严肃"的库需要一个通用的数组堆,需要一个'递减键'操作时,他们会怎么做?

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