バイナリ ヒープは、プライオリティ キューなどでよく使用されます。基本的な考え方は、不完全なヒープ ソートの考え方です。トップ要素をすばやく取り出すために、データを「十分に」ソートしたままにします。
4-ary ヒープは理論的にはバイナリ ヒープより劣りますが、いくつかの利点もあります。たとえば、必要なヒープの再構築操作は少なくなりますが (ヒープがはるかに浅いため)、明らかに各レベルでより多くの比較が必要になります。しかし (そしておそらくそれが彼らの主な利点でしょうか?) CPU キャッシュの局所性が向上している可能性があります。そのため、一部の情報源は、実際には 3 項ヒープと 4 項ヒープがフィボナッチ ヒープとバイナリ ヒープの両方よりも優れていると述べています。実装がそれほど難しくないはずです。追加のケースは単なる追加のif
ケースです。
プライオリティ キューの 4-ary ヒープ (および 3-ary) を試して、ベンチマークを行った人はいますか? Java では、広範囲にベンチマークを行うまで、速度が速いか遅いかはわかりません。そして、私がGoogleで見つけたすべてのものから、それは言語とユースケースにかなり依存している可能性があります. 一部の情報源は、3-ary が彼らにとって最高のパフォーマンスを発揮することを発見したと言っています。
さらにいくつかのポイント:
PriorityQueue
明らかにバイナリヒープです。しかし、たとえばクラスには、一括読み込みと一括修復のサポートが欠けているかreplaceTopElement
、大きな違いを生む可能性があります。たとえば、一括読み込みは;O(n)
の代わりです。O(n log n)
一括修復は、より大きな候補セットを追加した後も基本的に同じです。ヒープのどの部分が無効かを追跡するには、単一の整数を使用します。+replaceTopElement
よりもはるかに安価です(ポーリングがどのように実装されているかを考えてみてください: 一番上の要素を最後の要素に置き換えてください)poll
add
- もちろんヒープは複雑なオブジェクトに人気がありますが、優先順位は倍精度の整数であることがよくあります。ここで文字列を比較しているわけではありません。通常は(基本的な)優先度です
- PQ は、上位 k 個の要素を取得するためだけによく使用されます。たとえば、A*-search は、ゴールに到達したときに終了できます。その後、あまり良くないパスはすべて破棄されます。したがって、キューが完全に空になることはありません。4 ウェイ ヒープでは、順序が少なくなり、約半分 (親ノード数の半分) になります。したがって、必要のないこれらの要素に課される順序が少なくなります。(ヒープソートを行っているなどの理由で、ヒープを完全に空にする場合はもちろん異なります。)