ヒープから最大値のオブジェクトを継続的に抽出して処理するコードがあります。ただし、最大の処理中に、ヒープ内の他のオブジェクトが影響を受けるため、削除する必要がある場合があります。だいたい:
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 ヒープにはほとんど慣れていません)。線形検索を行わずにこれを行う方法を知っている人はいますか?