JavaでTreeMapのソースコードを調べていました。 Java docに従って:
赤黒木ベースのNavigableMap実装。マップは、使用されるコンストラクターに応じて、キーの自然な順序に従って、またはマップの作成時に提供されるコンパレーターによってソートされます。
この実装は、containsKey、get、put、およびremoveオペレーションに保証されたlog(n)時間コストを提供します。アルゴリズムは、Cormen、Leiserson、およびRivestの「Introduction to Algorithms」のアルゴリズムを応用したものです。
ソースコードで、内部クラスEntryがnode。
static final class Entry<K,V> implements Map.Entry<K,V> {
K key;
V value;
Entry<K,V> left = null;
Entry<K,V> right = null;
Entry<K,V> parent;
boolean color = BLACK;
....
赤黒木の定義については。私が見つけたウィキペディアから:
赤黒木は、コンピュータサイエンスで使用されるデータ構造である一種の自己均衡二分探索木です。
自己バランスは、各ノードを2色のいずれか(通常、「赤」と「黒」と呼ばれるため、樹木の名前と呼ばれます)でペイントすることで提供されます。 t著しく不均衡になるようにします。ツリーが変更されると、その後、新しいツリーが再配置および再描画され、カラーリングプロパティが復元されます。プロパティは、この再配置と再色付けを効率的に実行できるように設計されています。
私はソースコードを分析しようとしましたが、以下を理解できませんでした:
ツリーに「C」と「E」の2つのキーがすでにあり、「D」を追加するとします。ノードの配置方法(自然順序付けを使用)。
ツリーの自己バランスは、Javaソースコードに実装されています。
TreeMapの詳細な実装を検索してみましたが、次のような記事は見つかりませんでした 次の記事 HashMapで見つけました
昨日から私はこの木にぶら下がっています:(誰かが私が降りるのを助けてくれますか...
TreeMap
の目的は、親のキーよりも低いキーが左側にあり、親のキーよりも高いキーが右側にあるキーのツリーを持つことです。したがって、C
、次にE
を追加すると、次のツリーになります。
_C
\
E
_
次にD
を追加すると、最初は次のようになります。
_C
\
E
/
D
_
しかし、このツリーはバランスが取れていないため、検索が遅くなります。したがって、ツリーは再調整されます。バランス調整後、ツリーはより効率的になります。
_C C
\ rotate \ rotate D
E --- right ---> D --- left ---> / \
/ around \ around C E
D E E D
_
再調整はfixAfterInsertion()
メソッド内で行われ、ツリーの赤黒のプロパティが挿入後も維持されているかどうかをチェックします。また、そうでない場合は、問題のあるブランチでrotateLeft()
またはrotateRight()
のいずれかを実行するツリーのバランスを再調整して、バランスを復元します。次に、ツリーを上に移動してバランスをチェックし、ルートノードに到達するまで続けます。
赤黒木について詳しく説明しているインターネット上のリソースがいくつかあります。しかし、プロセスを理解する最良の方法は、次のようなアニメーションチュートリアルに従うことだと思います。 http://www.csanimated.com/animation.php?t=Red-black_tree
RBTのTreeMap
実装に固有のものはありません。これは、CLRS(Cormen、Leiserson、Rivest、Stein)の本に記載されている擬似コードに厳密に従っています。これは、実装の99%が行っていることです。