我使用的是这里的配对堆实现: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
上的日志因子会更快。方法相当简单:维护初始化到根(堆中的最小值(的最小值堆(带有指向树中节点的指针(。然后,您可以弹出辅助堆,将当前节点的子节点插入主堆中,这会更快,因为只有可能是下一个最小值的节点在队列中(它们是迄今为止所取节点的邻居(。
虽然这种方法的big-O复杂性在技术上更好,但在实践中几乎肯定会慢得多。这个最小配对堆的实现似乎非常高效,而且它几乎肯定会超过创建辅助堆和执行此搜索的开销。更不用说额外的代码复杂性和引入错误的可能性了,这可能不值得
我敢肯定,你做得再好不过O(k log k)
了。我的直觉是,如果你能做得更好,排序可能会持续减少时间,但基于比较的排序(iirc(已被证明不可能在比O(n log n)
更快的时间内解决。这种直觉可能是错误的,但我认为这可能非常接近事实。祝你好运!