これら2つのデータ構造の主な違いを誰かが説明できますか?相違点/類似点を強調するソースをオンラインで見つけようとしていますが、あまり有益なものは見つかりませんでした。どのような場合に一方が他方よりも優先されますか?どのような実際的な状況で、一方を他方よりも「使いやすく」しますか?
回答:
AVL木は、赤黒木よりも堅固なバランスを維持します。AVLツリーのルートから最も深い葉までのパスは最大で約1.44lg(n + 2)ですが、赤黒木では最大で約2 lg(n + 1)です。
その結果、AVLツリーでのルックアップは通常高速ですが、ローテーション操作が増えるため、挿入と削除が遅くなります。したがって、ルックアップの数がツリーの更新の数を支配すると予想される場合は、AVLツリーを使用してください。
小さなデータの場合:
挿入:RBツリーとavlツリーの最大回転数は一定ですが、平均してRBツリーの使用回転数が少ないため、RBツリーの方が高速になります。
ルックアップ:AVLツリーの深さが浅いため、AVLツリーの方が高速です。
削除:RBツリーの最大回転数は一定ですが、AVLツリーの回転回数は最悪の場合O(log N)回になる可能性があります。また、平均してRBツリーの回転数も少ないため、RBツリーの方が高速です。
大きなデータの場合:
挿入:AVLツリーの方が高速です。挿入する前に特定のノードを検索する必要があるためです。データが増えると、特定のノードを検索する際の時間差はO(log N)に比例して大きくなります。しかし、AVLツリーとRBツリーは、最悪の場合でも一定数の回転しか必要としません。したがって、ボトルネックは、その特定のノードを検索する時間になります。
ルックアップ:AVLツリーの方が高速です。(小さなデータの場合と同じ)
削除:AVLツリーは平均して高速ですが、最悪の場合、RBツリーは高速です。また、削除する前にスワップする非常に深いノードを検索する必要があるためです(挿入の理由と同様)。平均して、両方のツリーの回転数は一定です。しかし、RBツリーには回転の一定の上限があります。
これからの引用:AVLと赤黒木の違い
RBツリーはAVLツリーと同様に自己バランス型です。どちらもO(log n)ルックアップと挿入のパフォーマンスを提供します。違いは、RB-Treesが挿入操作ごとにO(1)回転を保証することです。これが、実際の実装で実際にパフォーマンスを犠牲にするものです。単純化されたRBツリーは、動的ノード構造のオーバーヘッドを持ち歩くことなく、概念的に2〜3ツリーであるという利点があります。物理的にRBツリーはバイナリツリーとして実装され、赤/黒フラグは2〜3の動作をシミュレートします。
したがって、定義上、すべてのAVLは赤黒のサブセットです。再構築や回転を行わずに、AVLツリーに色を付けて、赤黒木に変換できる必要があります。
AVLツリーは、同じ一連の操作をサポート
O(log n)
し、基本的な操作に時間がかかるため、赤黒木と比較されることがよくあります。ルックアップを多用するアプリケーションの場合、AVLツリーはより厳密にバランスが取れているため、赤黒木よりも高速です。赤黒木と同様に、AVL木は高さのバランスが取れています。どちらも一般に、μ≤½の場合、重量バランスもμバランスもありません。つまり、兄弟ノードの子孫の数は大きく異なる可能性があります。
AVLツリーに関するウィキペディアの記事から
AVLツリーがどのように機能するかを理解するには、このインタラクティブな視覚化が役立ちます。
AVLと赤黒木は高さのバランスが取れたツリーデータ構造です。それらは非常に似ており、実際の違いは、追加/削除操作で実行されるローテーション操作の数にあります。AVLの場合は、全体的により均一なバランスを維持するために多くなります。
どちらの実装も、としてスケーリングされますO(lg N)
。ここで、Nはリーフの数ですが、実際には、AVLツリーはルックアップを多用するタスクで高速です。より良いバランスを利用すると、ツリーの走査は平均して短くなります。一方、挿入と削除に関しては、AVLツリーは遅くなります。変更時にデータ構造を適切にリバランスするには、より多くの回転が必要になります。
汎用の実装(つまり、ルックアップが操作の主流であるかどうかは事前に明確ではありません)の場合、RedBlackツリーが推奨されます:実装が簡単で、一般的なケースでは高速です-データ構造が検索される頻度で変更される場合は常に。たとえば、TreeMap
およびTreeSet
バッキングRedBlackツリーのJavaでメイク使用。
赤黒木は回転が少ないという事実は、挿入/削除でそれらをより速くすることができます、しかし....。それらは通常少し深いので、挿入と削除で遅くなることもあります。ツリーのあるレベルから次のレベルに移動するたびに、要求された情報がキャッシュになく、RAMから取得する必要があるという大きな変化があります。したがって、より深くナビゲートする必要があり、したがってキャッシュをより頻繁に更新する必要があるため、より少ないローテーションで得られた時間はすでに失われる可能性があります。キャッシュから操作できるかどうかは大きな違いになります。関連情報がキャッシュにある場合は、追加のレベルをナビゲートするのに必要な時間内に複数のローテーション操作を実行でき、次のレベルの情報はキャッシュにありません。したがって、RedBlackが理論的に高速で、必要な操作のみを見る場合、実際には遅くなる可能性があります。
私が見たところ、AVLツリーはAVLツリーの目的の高さ(Log n)を取得するために、必要な数の回転(時々ツリーを再帰的に上る)を行うようです。これにより、より厳密にバランスが取れます。
赤黒木については、挿入と削除を確実に行うために必要な5セットのルールがあります。これらはhttp://en.wikipedia.org/wiki/Red-black_treeにあります。
赤黒木に役立つ可能性のある主なことは、これらの5つのルールに応じて、叔父が赤の場合、ルートまでツリーを再帰的に色付けできるという事実です。叔父が黒人の場合は、問題を解決するために最大2回転する必要がありますが、1〜2回転した後は完了です。それを詰めて、おやすみなさいと言ってください。それがあなたがしなければならない操作の終わりだからです。
大きなルールは5番です... '特定のノードからその子孫の葉のいずれかへのすべての単純なパスには、同じ数の黒いノードが含まれています。
これにより、ツリーを機能させるために必要な回転のほとんどが発生し、ツリーのバランスが崩れすぎないようになります。