プログラマーとして、いつRBツリー、Bツリー、またはAVLツリーの使用を検討すべきですか?選択を決定する前に考慮する必要がある重要なポイントは何ですか?
誰かが各ツリー構造のシナリオを使用して、キーポイントを参照して他のツリー構造を選択する理由を説明できますか?
回答:
塩ひとつまみでこれを取る:
何千ものアイテムを管理していて、ディスクや低速のストレージメディアからそれらをページングしているときのBツリー。
ツリーで頻繁に挿入、削除、取得を行う場合のRBツリー。
挿入および削除が検索に比べてまれな場合のAVLツリー。
B +ツリーは、メインメモリでも、汎用の順序付けされたコンテナーデータ構造として適しています。仮想メモリが問題ではない場合でも、キャッシュの使いやすさはしばしば問題になり、B +ツリーはシーケンシャルアクセスに特に適しています。リンクリストと同じ漸近的なパフォーマンスですが、キャッシュの使いやすさは単純な配列に近くなります。このすべてとO(log n)の検索、挿入、削除。
ただし、B +ツリーには問題があります。たとえば、挿入/削除を実行するとアイテムがノード内を移動し、それらのアイテムへのポインターが無効になるなどです。「カーソルメンテナンス」を実行するコンテナライブラリがあります。カーソルは、リンクリストで現在参照しているリーフノードにアタッチされるため、自動的に修正または無効化できます。カーソルが1つまたは2つを超えることはめったにないため、うまく機能しますが、まったく同じように追加の作業が必要です。
もう1つは、B +ツリーが本質的にそれだけであることです。必要かどうかに応じて、非リーフノードを削除または再作成できると思いますが、バイナリツリーノードを使用すると、柔軟性が大幅に向上します。バイナリツリーはリンクされたリストに変換でき、ノードをコピーせずに戻すことができます。ポインタを変更するだけで、それを別のデータ構造として扱っていることを覚えておいてください。とりわけ、これは、ツリーのO(n)マージがかなり簡単になることを意味します。両方のツリーをリストに変換し、それらをマージしてから、再びツリーに変換します。
さらに別のことは、メモリの割り当てと解放です。バイナリツリーでは、これをアルゴリズムから分離できます。ユーザーはノードを作成してから挿入アルゴリズムを呼び出し、削除するとノードを抽出できます(ツリーからノードを切り離しますが、メモリを解放しないでください)。BツリーまたはB +ツリーでは、明らかに機能しません。データはマルチアイテムノードに存在します。必要な新しいノードの数がわかるまで、ノードを変更せずに操作を「計画」し、それらを割り当てることができる挿入メソッドを作成するのは困難です。
赤黒vs AVL?それが大きな違いをもたらすかどうかはわかりません。私自身のライブラリには、ノードを操作するためのポリシーベースの「ツール」クラスがあり、さまざまな変換を含む、二重リンクリスト、単純なバイナリツリー、スプレーツリー、赤黒ツリー、および盗み取り用のメソッドがあります。これらのメソッドのいくつかは、私がいつか退屈していたために実装されただけです。treapメソッドをテストしたことすらありません。AVLではなく赤黒木を選んだ理由は、アルゴリズムを個人的によく理解しているからです。これは、アルゴリズムが単純であることを意味するのではなく、私がより親しんでいるのは単なる歴史の変化です。
最後にもう1つ、私は元々B +ツリーコンテナーを実験として開発しました。これは実際に終わったことのない実験の1つですが、他の人に繰り返すことを勧めるようなものではありません。必要なのが順序付けられたコンテナーだけである場合、最良の答えは、既存のライブラリーが提供するものを使用することです(C ++のstd :: mapなど)。私のライブラリは何年にもわたって進化し、安定するまでにかなりの時間がかかりました。そして、最近、それが技術的に移植不可能であることを発見しました(WRT offsetofの未定義の動作に依存します)。
メモリ内では、アイテムの数が32000を超えるとBツリーが有利になります... stx-btreeのspeedtest.pdfを見てください。
データ構造を選択するとき、次のような要素をトレードオフします
まず、Robert Harveyが参照するWikipediaの記事を読むことから始めます。
実用的には、Javaなどの言語で作業する場合、平均的なプログラマーは提供されているコレクションクラスを使用する傾向があります。パフォーマンスチューニングアクティビティで、コレクションのパフォーマンスに問題があることがわかった場合は、別の実装を探すことができます。ビジネス主導の開発で最初に考慮しなければならないことはほとんどありません。このようなデータ構造を手動で実装する必要があることは非常にまれです。通常、使用できるライブラリがあります。
when should I consider using
ではなくを尋ねましたwhen should I consider implementing
。最後の段落は真実ですが、この質問のコンテキストではあまり価値がありません。ライブラリを使用する場合でも、ビジネスのニーズに最適な構造を効果的に選択するには、アルゴリズムを理解する必要があります。