ハッシュテーブル (HashTable)
1. 関連概念
- ハッシュ関数: キーワードの保存場所は、この関数を介して計算できます。
- ハッシュの競合: 異なるキーワードのハッシュ関数によって計算された保存場所は一貫しています。
2. ハッシュ関数の選択 (よく使われる)
方法 | 導入 |
---|---|
直接注文 | キーの線形関数を使用してハッシュ アドレスを計算します: Hash(key)=A*key+B; シンプルで均一ですが、事前にキーの分布を知る必要があり、小規模で継続的な検索に適しています |
除数剰余法 | ハッシュ テーブルで使用できるアドレスの数を m とすると、m 以下で m に最も近い素数 p を除数として取り、ハッシュ関数 Hash(key) = key% に従います。 p(p<=m)、キーはハッシュアドレスに変換されます |
3. ハッシュ衝突 (よく使われる)
オープンハッシュ方式/ハッシュバケット方式/チェーンアドレス方式:
配列 + リンクされたリストの形式で実装:
- キーワードに対してハッシュ マッピングを実行し、各キーワードのハッシュ アドレスを計算すると、同じハッシュ アドレスを持つすべてのキーワードが同じ「バケット」に含まれます。
- 「バケット」内のすべての要素は、単一のリンク リストの形式で接続され、リンク リストの先頭ノードはハッシュ テーブルに格納されます。
- 「バケット」には、ハッシュ衝突のある要素が格納されます。
ハッシュの衝突が深刻な場合、「バケット」のサイズが非常に大きくなり、検索効率に影響するため、最適化できます。
- 別のハッシュ テーブルを使用して「バケット」を実装するか、検索ツリーを使用して「バケット」を実装します。
4.インターフェースと実装クラスを設定する
- Set インターフェースは Collection インターフェースを実装します。これは、順序付けられていないデータと繰り返されないデータを格納するために使用されます。
- HashSet、LinkedHashSet、および TreeSet は、Set インターフェイスの実装クラスです。
- LinkedHashSet は HashSet のサブクラスであるため、セットをトラバースするときに要素を挿入順に読み取ることができます。
- HashSet スレッドは安全ではなく、Set インターフェイスの主要な実装クラスであり、null 値のキーを格納できます。
- TreeSet はスレッド セーフではなく、基盤となる実装は赤黒木、つまりバランスの取れた検索ツリーです. 要素は比較可能な同じ型のデータである必要があるため、TreeSet は並べ替え用にカスタマイズできます。
4.0 一般的な方法
4.1 ハッシュセット
- 無秩序: 基礎となる配列のインデックス順ではなく、ハッシュ値によるデータの格納を指します。
- 非反復性: 要素を追加する場合、equals メソッドと対応する要素の型の hashCode メソッドを比較して、要素が繰り返されているかどうかを確認します。equals メソッドが true を返す場合、要素が繰り返されていることを意味します。
- スレッドは安全ではありません。これは Set インターフェイスの主要な実装クラスであり、null 値のキーを格納できます。
- 要素の挿入操作:
1) まず、要素 x の対応するクラスの hashCode メソッドを介して、要素 x のハッシュ値 hashVal を計算します;
2) 特定のアルゴリズムを使用して、ハッシュ テーブル内の要素 x のハッシュ アドレス hashIndex を計算します。 hashVal:
hashIndex が存在するかどうかを確認します 既に要素があります: (1) 要素がない場合は、この位置に x を直接格納します; (2) 要素がある場合は、このハッシュ バケット内の各要素と順番に比較されます。トラバーサル比較処理中に、既存の要素が x と同じハッシュ値を持ち、equals メソッドが true を返した場合、それは重複要素があることを意味し、追加は失敗します;そうでない場合、ハッシュ値が同じであるが、 equals メソッドが false を返すか、ハッシュ値が異なる場合、チェーンの最後まで単方向リンク リストをトラバースし続けます。重複する要素がなく、追加が成功したことを意味します。 - 要件: 1) 追加する要素のクラスは、hashCode メソッドと equals メソッドを書き換える必要があります; 2) 書き換えられた hashCode メソッドと equals メソッドは、可能な限り一貫性を確保します: equal オブジェクトは同じハッシュ コードを持つ必要があります。
4.2 リンクされたハッシュセット
- HashSet のサブクラスとして、HashSet に基づいて拡張され、追加されたすべての要素が追加された順序でリンクされたリストの形式で接続されます。これは、頻繁な走査操作に便利です。
- null 値を格納できるキー。
- 各要素が格納されると、2 つの参照が同時に維持されます。1 つは先行ノード用で、もう 1 つは後続ノード用です。
4.3 ツリーセット
-
TreeSet スレッドは安全ではありません。基本的な実装は赤黒木、つまりバランスのとれた検索ツリーです。要素は同じ型のデータである必要があり、要素間で比較できるため、TreeSet は自然な並べ替えを実行できます (java. lang.Comparable インターフェイス) またはカスタム ソート (java.lang.Comparable インターフェイス) .util.Comparator インターフェイス);
-
自然な並べ替えでは、TreeSet に要素を追加するときに、要素が配置されているクラスで compareTo() メソッドを使用してサイズを比較し、戻り値が 0 の場合は、2 つの要素の内容が同じであることを意味します。
-
Under custom sorting, when adding elements to the TreeSet, use the compare() method in the Comparator passed in when the TreeSet object is instantiated for size comparison. 戻り値が 0 の場合、2 つの要素の内容が同じ;
4.4 例
出典:Shang Silicon Valley