Javaのコレクションフレームワークのソースコード解析(5.1 - マップのTreeMap、赤黒木)

Javaのコレクションフレームワークのソースコード解析(5.1 - マップのTreeMap、赤黒木)

Map複数のデータ構造、仕事や面接でのかどうかでJavaコレクションフレームワークのデザイン関連の知識が頻繁に関与することになります。学習によってMap、ソースコードを、私たちは、データ構造の深い知識と理解、コーディングスキルのかなりの部分にできました。データ構造のいくつかの知識を紹介します次のいくつかの記事で、私は容量のこの部分は、コアコンピタンスプログラマとして使用されているので、あなたが、退屈されないことを願っています。同時に、この部分の知識は、実際にそれほど深くないが、私が理解する最も簡単な方法であなたをお手伝いします。

地図インタフェース

Mapデータ構造の特徴が明確で、それは、私たちは、キーストアを使用して要素を読み取ることができ、かつ重複キーを許可していません。異なるMap順次処理キーの実装は矛盾しています。例えば、HashMap我々はキーの順序を保証することはできません、とTreeMapキーをに従って実装されるComparator順序を決定するためのインターフェイスメソッド。

Map各々が、対応するキー値データが実装しなければならない定義にEntryインターフェースを、上記に規定された方法は、キーと値のための基本的操作も非常に簡単です。

Mapインターフェイスで定義された方法は、我々はすべて私がここで長いったらしいないんだけど、とより多くの知識が必要です。特に、私はいくつかの方法を言及しますJDK8は、日常業務におけるより実用的な追加。あなたが前にいないJDK8経験をすれば、あなたは見つけることができます。

* `getOrDefalut(Object key, V defaultValue)`:当 `Map` 中有 key 对应的 value 时返回 `Map` 中的 value, 否则返回 `defaultValue` 。
* `V compute(K key,BiFunction<? super K, ? super V, ? extends V> remappingFunction)`:将 `Map` 中的 key 和对应的 value 作为参数,调用 `remappingFunction` 方法获得 newValue,如果 newValue 不为 null,则替换原来的 value。
* `V putIfAbsent(K key, V value)`:如果当前 `Map` 中没有 key 对应的 value,则执行 put 操作。
* `V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)`:如果当前没有 key 对应的 value,则将参数 value 放入 `Map` 中,否则将原来 key 对应的 value 和新的 value 作为参数调用 `remappingFunction` ,将结果 put 入 `Map` 中。
复制代码

これらのメソッドの実装Mapインタフェースは、のJDK8新しい利用defaultの下位互換性を維持するためのキーワードは、特定のコードが長いったらしいがない、非常に簡単です。

TreeMapの

比較的HashMapTreeMap知識が精通などのいくつかのあまり適切に関与Map飛び石のデータ構造。そのクラス図で見てみましょう:

私たちは見ることができますTreeMap継承AbstractMapと実装NavigableMapのインターフェイスを。AbstractMap開発者が独自に実装するための方法は、テンプレートの一部を提供しMap、そしてNavigableMap前述の類似提供NavigableSetこれらのメソッドには、キーまたは値の範囲を返すことができます。だから我々はまっすぐに向かうTreeMap特定の実装の詳細。

コメントの最初から知られている、TreeMap赤黒ツリーデータ構造によって達成され、それが確保することが可能であるcontainsKeygetputremove時間の複雑さがありますlog(n)そして、同じことは、TreeMapスレッドセーフではありません。だから、本当に理解TreeMapキーは赤黒ツリーデータ構造を理解し、把握することです。次の部分だから、私はあなたがこれは非常に困難な作業であるとは思わない、赤黒木の性質をブラッシュアップに役立ついくつかの長さを過ごすことになり、私はあなたが読んだ後の一連の記事では、Java手書きで赤黒木のことができるようになることを保証します。

バランスの取れたバイナリツリー

一文は赤黒木は平衡二分木バイナリツリーの概念は、我々はすべて、それぞれの親がツリーの2つの以下の子ノードを持っていないことを知っている必要があります。バランス左右の部分木の高さは1個以下だけ異なることを意味します。同時に電流よりも小さい全てのノード左サブツリーの値、及び大電流よりも右側に、ツリーの子ノードの値。いくつかの例で見てみましょう。

図1に見ることができます左と右のサブツリーは、よりの高さよりによって異なるため、我々は図2に準拠した前述のではなく、条件に合わせて、バランスの取れたバイナリツリーです。

バランスの取れたバイナリツリー

非平衡二分木

目的は、複雑さを保つために時間を見つけるためにバイナリ検索を行うことができるように、リンクリストにバランスの取れたバイナリツリーの退化を維持することではありませんlog(n)それはまた、特別な操作を行う必要があり、このような赤黒木データ構造であり、全体の二分木のバランスを維持する際に削除されたノードまたはノードの増加を意味します。

赤、黒の木

それは平衡二分木のすべての特性を有するように述べた以前のように、赤黒木は、平衡二分木自体です。これに基づき、それは彼ら自身のユニークな特性を持ついくつかの制約があります。

各追加ノードは赤黒の木が特徴的な色を追加し、すなわち、赤黒木に、その名前の由来である、赤、または黒、これらの二つの内の一方のみ。私たちは見てTreeMap赤黒ツリーノードのソース:

static final class Entry<K,V> implements Map.Entry<K,V> {
    K key;
    V value;
    Entry<K,V> left;
    Entry<K,V> right;
    Entry<K,V> parent;
    boolean color = BLACK;
}
复制代码

TreeMap各ノード実装Map現在のキーを表すノードの下の左と右の子ノードに加えて、入力インターフェイス、値2つのデータ項目、ならびにコード自体は、ノードleftおよびrightその親ノードとしても、parent最後は、現在のノードの色を表現することcolor、ここで同じ定義TreeMapソースコード:

private static final boolean RED   = false;
private static final boolean BLACK = true;
复制代码

その後、我々は赤黒木の特性を見てみましょう。

* 根节点(root node) 的颜色始终为黑色
* 两个相邻的节点(即连接在一起的节点)不能同为红色
* 从根节点出发,到某个子节点的每条路径上的黑色节点数量都相同
复制代码

どうでしょうか?シンプル十分!次に例を見てみましょう。

ビューの上記のチャートから、我々が記載されている三つの特徴を満たす前に、必ず赤黒木の概念の正しい理解を確認します。

3赤黒木の基本的な操作

あなたは赤黒木の概念を習得している必要があります上記の説明を通して、あなたは赤黒木が何であるかを知っています。赤黒木の挿入や削除操作を導入する前に、我々は最初の三つの基本的な操作を学び、その変更の色(カラーフリップ)、左回転(左回転)と右回転(右回転)。

色の変化

赤色の非常に単純な、現在のノードの色は、左と右の子ノードの色を黒に変更されます。図に。

左と右回転

要約を記述するためにいくつかの単語があるかもしれません、我々は、例えば、画像、ウィキペディアからの映像を見てください。

Duokanjibianこの絵は、これら三つの基本的な動作は、後続の赤黒木の挿入や削除操作の基礎であるので、あなたは、左時計回りに回転し、反時計回りの意味を理解してください。

エピローグ

導入された主MapおよびTreeMapいくつかの基本的な機能、及びTreeMap赤黒木の根底にある基本的な概念。赤黒木は、開発者にとってより重要なレベルのデータ構造は精通している必要がありあり、これは基本的な概念と操作ベースを紹介します。そして、我々は赤黒木の削除操作に関与することになります次のアルゴリズムの特定を挿入し、それは、この基盤に基づいているため、この部分に入る前に、私は再び、この記事の内容を理解強調する。

次回の記事で私が制御するTreeMap赤黒木アルゴリズムのソースコードの導入を、私はあなたがお見逃しなく願っています!

私は、より質の高い記事をマイクロ信号に注意を歓迎「し、人々のユリ」

おすすめ

転載: juejin.im/post/5e6ae265518825491949814f