我有一些代码可以不断地从堆中提取最大值对象并对其进行处理。但是,在处理最大值期间,堆中的其他对象会受到影响,可能需要被删除。大致:
vector<HeapEntry*> myHeap = vector<HeapEntry*>();
fillHeap(myHeap, someData);
make_heap(myHeap.begin(), myHeap.end());
while (!myHeap.empty())
{
HeapEntry* hp = myHeap.front();
HeapEntry* neighbor = hp->getNeighbor();
if (someCondition)
{
remove(myHeap, neighbor);
}
//more processing of hp
}
和删除功能:
void remove(vector<HeapEntry*> myHeap, HeapEntry* toRemove)
{
for (it = myHeap.begin(); it != myHeap.end(); it++)
{
if (*it == hp)
{
myHeap.erase(it);
break;
}
}
make_heap(myHeap.begin(), myHeap.end());
}
这运行并给出正确的输出。但它非常慢:处理一个 40kb 的文件需要 2 分钟(堆的大小与文件的大小成线性关系)。无论如何,它需要更有效率。
remove 函数最终会被调用大约 n 次,其中 n 是堆的大小。因此,进行线性搜索会使整个算法变为 O(n^2)。我认为这就是问题所在,我相信这可以在 O(n*log(n)) 中运行。
我的目标是在 O(log(n)) 时间内完成删除功能。就像是:
- 直接进入目标元素
- 用最后一个元素切换它
- pop_heap(myHeap.begin(), myHeap.end()); myHeap.pop_back();
- make_heap(myHeap.begin(), myHeap.end());
我不太确定如何实现这一点(我对 stl 堆几乎不熟悉)。有谁知道如何在不进行线性搜索的情况下做到这一点?