将 minheap.top 移动到 maxheap.top <= minheap.top 的 maxheap.top

Moving minheap.top to maxheap.top where maxheap.top <= minheap.top

本文关键字:top maxheap minheap lt 移动      更新时间:2023-10-16

我有一个maxheap和一个minheap,其中maxheap的最大元素小于或等于minheap的最小元素。

我现在想移动最小堆的最小元素成为最大堆的最大元素。

一种方法是弹出最小堆的顶部元素并将其推送到最大堆上。

有没有更有效的方法可以做到这一点?

这是我最终做的事情

实际上必须将一个元素插入到minheap中,然后执行上述操作,我做了以下操作:

// place value to insert at end of minheap
mintoph[mintoph_size] = R;
// use std::pop_heap, minimum element now at end
pop_heap(mintoph.begin(), mintoph.begin() + mintoph_size + 1, greater<int>());
// (*) make room in maxheap at top
for (int pos = maxboth_size++; pos > 0;)
{
    int parent = (pos - 1) / 2;
    maxboth[pos] = maxboth[parent];
    pos = parent;
}
// move element from back of minheap to maxheap head
maxboth[0] = mintoph[mintoph_size];

在上面的第 (*) 步中,已经支付的比较是浪费的,因为父母被降级为孩子,但我认为这是不可避免的。

当您知道要插入的元素小于/大于最小/最大时,您真正需要的是一种插入优先级队列的有效方法,具体取决于这是最小堆还是最大堆。 对于传统的"堆"数据结构,这需要 O(log n) 时间。

但是,如果您愿意为优先级队列使用与传统的"堆"数据结构不同的表示形式,那么这样的插入可以简单地在 O(1) 时间内运行。 许多不同类型的优先级队列都可以执行此操作,例如左堆、倾斜堆或配对堆。

编辑:当然,您仍然需要支付从原始优先级队列中删除的成本,无论如何都可能是O(log n),尽管有些方法也可能有所帮助,例如"惰性删除"。

您可能

最好使用 min-max-heap 或 treap。 min-max-heap 似乎是为您正在做的事情量身定制的,但 treap 非常全面,它们也可能运行良好 - 特别是如果您需要的不仅仅是查找最小值和最大值并添加值。

http://en.wikipedia.org/wiki/Min-max_heap

http://en.wikipedia.org/wiki/Treap

使用 min-max 堆,它是一个双端优先级队列,你可以在 o(lgn) 中做这件事,你不能在小于 O(lgn) 中做这件事

但是你可以使用它们插入 O(1) 中的摊销算法,如斐波那契堆,