web-dev-qa-db-ja.com

RBツリー、Bツリー、またはAVLツリーを選択する場合

プログラマーとして、RBツリー、Bツリー、またはAVLツリーの使用をいつ検討すべきですか?選択を決定する前に考慮する必要がある重要なポイントは何ですか?

誰かが各ツリー構造のシナリオで、重要な点を参照して他のツリー構造よりも選択される理由を説明してください。

85
Palladin

ひとつまみの塩でこれを取る:

数千を超えるアイテムを管理していて、それらをディスクまたは低速のストレージメディアからページングしている場合のBツリー。

ツリーでかなり頻繁に挿入、削除、取得を行っているときのRBツリー。

挿入および削除が取得に関連する頻度が低い場合のAVLツリー。

108
blwy10

B +ツリーは、メインメモリ内であっても、優れた汎用の順序付けられたコンテナデータ構造であると思います。仮想メモリが問題にならない場合でも、多くの場合キャッシュが使いやすく、B +ツリーはシーケンシャルアクセスに特に適しています。リンクリストと同じ漸近的なパフォーマンスですが、キャッシュの使いやすさは単純な配列に近いものです。このすべてとO(log n)の検索、挿入、削除。

ただし、B +ツリーには問題があります。たとえば、挿入/削除を行うときにノード内でアイテムが移動し、それらのアイテムへのポインターが無効になるなどです。 「カーソルメンテナンス」を行うコンテナライブラリがあります。カーソルは、リンクリストで現在参照しているリーフノードに自分自身をアタッチするため、自動的に修正または無効化できます。カーソルが1つまたは2つを超えることはめったにないため、うまく機能しますが、それでも余分な作業がすべて同じです。

別のことは、B +ツリーは本質的にそれだけであることです。必要かどうかに応じて、葉以外のノードを削除または再作成できると思いますが、バイナリツリーノードを使用すると、柔軟性が大幅に向上します。ノードをコピーせずに、バイナリツリーをリンクリストに変換し、元に戻すことができます。ポインターを変更するだけで、今は別のデータ構造として扱っていることに注意してください。とりわけ、これはかなり簡単にO(n)ツリーをマージすることを意味します-両方のツリーをリストに変換し、それらをマージしてから再びツリーに変換します。

さらに別のことは、メモリの割り当てと解放です。バイナリツリーでは、これをアルゴリズムから分離できます。ユーザーはノードを作成してから挿入アルゴリズムを呼び出し、削除によってノードを抽出できます(ツリーからノードを切り離しますが、メモリを解放しないでください)。 BツリーまたはB +ツリーでは、それは明らかに機能しません。データはマルチアイテムノードに存在します。必要な新しいノードの数と割り当て可能なノードがわかるまで、ノードを変更せずに操作を「計画」する挿入メソッドを作成するのは困難です。

赤黒vs AVL?それが大きな違いを生むかどうかはわかりません。私自身のライブラリには、ノードを操作するためのポリシーベースの「ツール」クラスがあり、さまざまな変換を含む、二重リンクリスト、単純なバイナリツリー、スプレイツリー、赤黒ツリー、およびトレープのメソッドがあります。これらの方法のいくつかは、私がいつか退屈していたためにのみ実装されました。 treapメソッドをテストしたかどうかはわかりません。私がAVLではなく赤黒の木を選んだ理由は、私がアルゴリズムを個人的によく理解しているからです。

最後に、実験としてB +ツリーコンテナを最初に開発しただけです。これは、決して終わらない実験の1つですが、他の人に繰り返すことをお勧めするものではありません。必要なのが順序付けされたコンテナだけである場合、最良の答えは、既存のライブラリが提供するものを使用することです-例えばC++のstd :: mapなど。私のライブラリは何年​​もかけて進化し、安定させるのにかなりの時間がかかり、比較的最近、それが技術的に移植不可能であることを発見しました(WRT offsetofの未定義の動作に依存します)。

19
Steve314

メモリ内のBツリーには、アイテム数が32000を超える場合に利点があります... speedtest.pdf from stx-btree をご覧ください。

4
stan5

データ構造を選択するとき、次のような要因をトレードオフします

  • 検索の速度v更新の速度
  • ソートされた順序で到着するレコードの挿入など、最悪のケースの操作に構造がどれだけうまく対処できるか
  • 無駄なスペース

ロバート・ハーベイが参照したウィキペディアの記事を読むことから始めます。

実用的には、Javaなどの言語で作業する場合、平均的なプログラマーは提供されているコレクションクラスを使用する傾向があります。ビジネス主導の開発が最初に考慮しなければならないことはめったにありません。

0
djna