最初の選択は、予想されるアクセスパターンと、保存する可能性のあるデータの量によって異なります。...
- データがそれほど多くない場合(たとえば、30未満)、ソートされていない配列で問題ありません。
- 追加、削除、または更新することがほとんどない場合は、ソートされた配列で問題ありません。
- nがたとえば100万未満で、最上位の要素(最初または最後にランク付けされた要素)のみを検索している場合、ヒープは適切に機能します(特に、ランダムに選択された要素を頻繁に更新する場合は、たとえば、キャッシュのLRU(最近使用されていない)キューで実行します。これは、平均して、このような更新がO(log(n))ではなくO(1)であるためです。
- nがたとえば100万未満で、何を検索するかわからない場合は、バランスの取れたツリー(たとえば、赤黒またはAVL)で問題ありません。
- nが大きい場合(たとえば、100万以上)、bツリーまたはトライを使用したほうがよいでしょう(nが十分に大きくなると、バランスの取れた二分木のパフォーマンスは「崖から落ちる」傾向があります。メモリアクセス散らばりすぎる傾向があり、キャッシュミスは本当に傷つき始めます)
...ただし、オプションをできるだけ開いたままにして、少なくとも1つの選択肢のベンチマークを行い、パフォーマンスが向上した場合はそれに切り替えることができるようにすることをお勧めします。
過去20年間、私はヒープが何にでも最適な2つのアプリケーションにのみ取り組んできました(1回はLRUで、もう1回は厄介なオペレーションズリサーチアプリケーションで、ランダムに摂動されたk次元超立方体への加法性を復元します。ハイパーキューブ内のセルはk個の異なるヒープに表示され、メモリは貴重でした)。ただし、これら2つの場合、それらは代替案よりもはるかに優れたパフォーマンスを示しました。バランスの取れたツリーやbツリーよりも文字通り数十倍高速です。
前の段落で述べたハイパーキューブの問題について、私のチームリーダーは、赤黒木はヒープよりもパフォーマンスが優れていると考えていましたが、ベンチマークでは、赤黒木ははるかに遅いことが示されました(覚えているように、約20倍遅い) )、そしてb-treeはかなり高速でしたが、ヒープもそれらを快適に打ち負かしました。
ヒープの重要な機能は、上記の両方の場合で、最小値のO(1)ルックアップではなく、ランダムに選択された要素のO(1)平均更新時間でした。
-James Barbetti(まあ、私はそうだと思っていました。しかし、キャプチャは私が人間ではないと言い続けています)