在最小配对堆中找到 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)
更快地解决。这种直觉可能是错误的,但我认为它可能非常接近事实。祝你好运!
我正在使用此处找到的配对堆实现: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)
更快地解决。这种直觉可能是错误的,但我认为它可能非常接近事实。祝你好运!