赤黒木とAVL木の違い


82

これら2つのデータ構造の主な違いを誰かが説明できますか?相違点/類似点を強調するソースをオンラインで見つけようとしていますが、あまり有益なものは見つかりませんでした。どのような場合に一方が他方よりも優先されますか?どのような実際的な状況で、一方を他方よりも「使いやすく」しますか?

回答:


100

AVL木は、赤黒木よりも堅固なバランスを維持します。AVLツリーのルートから最も深い葉までのパスは最大で約1.44lg(n + 2)ですが、赤黒木では最大で約2 lg(n + 1)です。

その結果、AVLツリーでのルックアップは通常高速ですが、ローテーション操作が増えるため、挿入と削除が遅くなります。したがって、ルックアップの数がツリーの更新の数を支配すると予想される場合は、AVLツリーを使用してください。


3
概念をよりよく理解するように求める。avlツリーとRedBlackツリーはどちらも、挿入ごとに最大2回転します。では、AVLツリーはどのように遅いと言えますか?前もって感謝します!
user2626445 2014

@larsmans!パフォーマンスの違いが大きすぎて、新しいコンセプトが生まれていますか?
Shashwat 2014年

@Shashwat私はあなたが何を意味するのかわかりません。新しいコンセプト?
Fred Foo

2
@larsmans!挿入、削除、更新のパフォーマンスにわずかな違いがあるだけなのに、AVLツリーがあるのになぜ赤黒木の概念がそれほど有名なのかということです。赤黒木とAVL木が違う大きな点はありますか?
Shashwat 2014年

それらを維持するためのアルゴリズムは異なるため、異なる名前が付けられます。AFAIK、それらは同じbig-O時間境界で同じ操作のセットをサポートします。
フレッドフー

54

小さなデータの場合

挿入:RBツリーとavlツリーの最大回転数は一定ですが、平均してRBツリーの使用回転数が少ないため、RBツリーの方が高速になります。

ルックアップ:AVLツリーの深さが浅いため、AVLツリーの方が高速です。

削除:RBツリーの最大回転数は一定ですが、AVLツリーの回転回数は最悪の場合O(log N)回になる可能性があります。また、平均してRBツリーの回転数も少ないため、RBツリーの方が高速です。

大きなデータの場合

挿入:AVLツリーの方が高速です。挿入する前に特定のノードを検索する必要があるためです。データが増えると、特定のノードを検索する際の時間差はO(log N)に比例して大きくなります。しかし、AVLツリーとRBツリーは、最悪の場合でも一定数の回転しか必要としません。したがって、ボトルネックは、その特定のノードを検索する時間になります。

ルックアップ:AVLツリーの方が高速です。(小さなデータの場合と同じ)

削除:AVLツリーは平均して高速ですが、最悪の場合、RBツリーは高速です。また、削除する前にスワップする非常に深いノードを検索する必要があるためです(挿入の理由と同様)。平均して、両方のツリーの回転数は一定です。しかし、RBツリーには回転の一定の上限があります。


2
これは、AVLツリーが大量のデータでほとんど常に好まれるということを意味しているようです。なぜJavaとC ++ STLで使用されるのですか?stackoverflow.com/questions/3901182/...
emschorsch

挿入/削除の場合にAVLツリーをRBツリーよりも優れたものにするには、一定量のデータ(たとえば、100万)が必要です。これは、実際には実装方法によって異なります。スマートAVL実装は、データ量が少なくてもstd :: mapを打ち負かすことができます。たとえば、親
。– DU Jiaen 2016

これは優れた分析であり、データ構造のあらゆる種類の比較の模範となるはずです。受け入れ答えよりも良い
pterodragon

1
「小さなデータ」の要約として、私がこれから得たのは、AVLは前もってより多くの作業を行い、後でパフォーマンスを向上させるために(書き込み/ローテーション)より厳密になります(読み取り)。書き込むよりも読み取る量が増えるため、データが大きくなるにつれて読み取りが重要になります(ローテーションは検索と比較して重要ではありません)。したがって、AVLは読み取り用に最適化されているため、すべての点で勝ちます。
ベンバターワース

8

これからの引用:AVLと赤黒木の違い

RBツリーはAVLツリーと同様に自己バランス型です。どちらもO(log n)ルックアップと挿入のパフォーマンスを提供します。違いは、RB-Treesが挿入操作ごとにO(1)回転を保証することです。これが、実際の実装で実際にパフォーマンスを犠牲にするものです。単純化されたRBツリーは、動的ノード構造のオーバーヘッドを持ち歩くことなく、概念的に2〜3ツリーであるという利点があります。物理的にRBツリーはバイナリツリーとして実装され、赤/黒フラグは2〜3の動作をシミュレートします。

したがって、定義上、すべてのAVLは赤黒のサブセットです。再構築や回転を行わずに、AVLツリーに色を付けて、赤黒木に変換できる必要があります。


3

AVLツリーは、同じ一連の操作をサポートO(log n)し、基本的な操作に時間がかかるため、赤黒木と比較されることがよくあります。ルックアップを多用するアプリケーションの場合、AVLツリーはより厳密にバランスが取れているため、赤黒木よりも高速です。赤黒木と同様に、AVL木は高さのバランスが取れています。どちらも一般に、μ≤½の場合、重量バランスもμバランスもありません。つまり、兄弟ノードの子孫の数は大きく異なる可能性があります。

AVLツリーに関するウィキペディアの記事から


3

木の最大の高さは、バランスを保つために最も重要です。1.44 * log(n)AVLの場合はほぼ同じですが、RBツリーの場合は2 * log(n)です。したがって、問題が検索インセンティブである場合は、AVLを使用する方がよいという結論を得ることができます。重要なのは、AVLおよびRBツリーに関する別の質問です。ローテーションのコストを抑えてランダム挿入に直面する場合、RBツリーはAVLよりも優れていますが、昇順または降順のデータを挿入するのに適したAVLです。したがって、問題が挿入インセンティブである場合は、RBツリーを使用できます。


3

AVLツリーがどのように機能するかを理解するには、このインタラクティブな視覚化が役立ちます。

AVLと赤黒木は高さのバランスが取れたツリーデータ構造です。それらは非常に似ており、実際の違いは、追加/削除操作で実行されるローテーション操作の数にあります。AVLの場合は、全体的により均一なバランスを維持するために多くなります。

どちらの実装も、としてスケーリングされますO(lg N)。ここで、Nはリーフの数ですが、実際には、AVLツリーはルックアップを多用するタスクで高速です。より良いバランスを利用すると、ツリーの走査は平均して短くなります。一方、挿入と削除に関しては、AVLツリーは遅くなります。変更時にデータ構造を適切にリバランスするには、より多くの回転が必要になります。

汎用の実装(つまり、ルックアップが操作の主流であるかどうかは事前に明確ではありません)の場合、RedBlackツリーが推奨されます:実装が簡単で、一般的なケースでは高速です-データ構造が検索される頻度で変更される場合は常に。たとえば、TreeMapおよびTreeSetバッキングRedBlackツリーのJavaでメイク使用。


2

赤黒木は回転が少ないという事実は、挿入/削除でそれらをより速くすることができます、しかし....。それらは通常少し深いので、挿入と削除で遅くなることもあります。ツリーのあるレベルから次のレベルに移動するたびに、要求された情報がキャッシュになく、RAMから取得する必要があるという大きな変化があります。したがって、より深くナビゲートする必要があり、したがってキャッシュをより頻繁に更新する必要があるため、より少ないローテーションで得られた時間はすでに失われる可能性があります。キャッシュから操作できるかどうかは大きな違いになります。関連情報がキャッシュにある場合は、追加のレベルをナビゲートするのに必要な時間内に複数のローテーション操作を実行でき、次のレベルの情報はキャッシュにありません。したがって、RedBlackが理論的に高速で、必要な操作のみを見る場合、実際には遅くなる可能性があります。


1

私が見たところ、AVLツリーはAVLツリーの目的の高さ(Log n)を取得するために、必要な数の回転(時々ツリーを再帰的に上る)を行うようです。これにより、より厳密にバランスが取れます。

赤黒木については、挿入と削除を確実に行うために必要な5セットのルールがあります。これらはhttp://en.wikipedia.org/wiki/Red-black_treeにあります。

赤黒木に役立つ可能性のある主なことは、これらの5つのルールに応じて、叔父が赤の場合、ルートまでツリーを再帰的に色付けできるという事実です。叔父が黒人の場合は、問題を解決するために最大2回転する必要がありますが、1〜2回転した後は完了です。それを詰めて、おやすみなさいと言ってください。それがあなたがしなければならない操作の終わりだからです。

大きなルールは5番です... '特定のノードからその子孫の葉のいずれかへのすべての単純なパスには、同じ数の黒いノードが含まれています。

これにより、ツリーを機能させるために必要な回転のほとんどが発生し、ツリーのバランスが崩れすぎないようになります。


1

要約すると、AvlTreeはRedBlackTreeよりもわずかにバランスが取れています。両方のツリーは、ルックアップ、挿入、および削除に全体でO(log n)時間を要しますが、挿入と削除の場合、前者はO(log n)回転を必要とし、後者はO(1)回転のみを必要とします。

ローテーションはメモリへの書き込みを意味し、メモリへの書き込みにはコストがかかるため、RedBlackTreesは実際にはAvlTreesよりも更新が高速です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.