在最小配对堆中找到 N 个最小值的有效算法

Efficient algorithm for finding N min values in a min pairing-heap

我正在使用此处找到的配对堆实现:https://github.com/jemalloc/jemalloc/commits/dev/include/jemalloc/internal/ph.h

虽然我偶尔需要迭代堆中的 N 个最小值(其中 N 受堆中元素数的限制,但通常更少)。有什么有效的方法吗?

我目前的方法是调用 remove_first() N 次,然后通过 insert().

将所有弹出的元素推回

您的方法是 O(k log n),其中 k 是您要打印的项目数,n 是堆中的元素数。看起来这些操作在您使用的实现中得到了相当广泛的优化。有一种方法可以用另一个堆遍历堆来解决您在 O(k log k) 中的目标,使用 k 上的对数因子比 n 上的对数因子更快。该方法相当简单:维护 min-heap 个值(带有指向树中节点的指针)初始化为根(这是堆中的最小值)。然后,您可以弹出辅助堆并将当前节点的子节点插入主堆中,这样速度更快,因为队列中只有可能是下一个最小值的节点(它们是您已经创建的节点的邻居)到目前为止)。

虽然这种方法的 big-O 复杂性在技术上更好,但在实践中几乎肯定会慢得多。这个 min-pairing 堆的实现看起来非常有效,而且几乎肯定会超过创建辅助堆和执行此搜索的开销。更不用说额外的代码复杂性和引入错误的可能性,这可能是不值得的。

我很确定你不能比 O(k log k) 做得更好。我对此的直觉是,如果你能做得更好,排序的时间可能会不断减少,但 comparison-based 排序 (iirc) 已被证明不可能比 O(n log n) 更快地解决。这种直觉可能是错误的,但我认为它可能非常接近事实。祝你好运!