ハッシュ関数は
非ハッシュテーブル機能:テーブルのキーの位置を、それが決定したとの間の関係は存在しません、キーワードごとに、一度見てのプロセスは、検索効率に応じて、指定した値を比較し、与えられました値は、比較の数です。
これは、ハッシュテーブルを備え:キーワードは、テーブルや位置、それとの間に明確な関係が存在します。
ハッシュ関数は:通常の状況下では、それはテーブル内のレコードのキー位置のためのキーとしてF(キー)に機能してテーブル内の位置を記憶されたキーワードとの間に確立する必要があるが、通常は関数fと呼ばれます(キー)は、ハッシュ関数です。
ハッシュ:「ハッシュ」として翻訳は、ハッシュアルゴリズムを介して、出力への固定長出力は、ハッシュ値は、任意の長さの入力です。
この変換は、空間ハッシュ値は、典型的には、入力空間よりもはるかに小さい圧縮マップ、である、異なる入力が同じ出力にハッシュすることができる、一意のハッシュ値から入力値を決定することは不可能です。
単に手段メッセージダイジェストモイ固定長の圧縮関数に任意の長さAのメッセージという。
ハッシュの競合:(これはハッシュマップの値を維持する方法である)を取得する関数f(キー)の後に、キーの結果に基づいており、現在のキー値キー値を格納するためのアドレスとして、ですが、それは最初のカウント・アウトのアドレスことが判明しました来ます。その場所は、それを奪われました。これは、ハッシュの衝突の友人と呼ばれています。
紛争へのハッシュ関数アプローチ
1.対処する方法:
mは、テーブルの長さであることを特徴とする請求
増分ジ三つのエミュレートは:
プローブ線形再ハッシュジ= 1、2、3、 ...、M-1
平方プローブ再ハッシュジ= 1 2、-2、4 、 - 4、8、-8、...、K、正方形、-k乗
ランダムハッシュディプローブは、次いで、擬似乱数シーケンスのセットであります
2.方法のリンクアドレス
、この方法の基本的な考え方は、すべてのアドレスハッシュ同義語鎖は要素Iと呼ばれる単一のリンク・リストを形成するために、単一のリストの先頭ポインタとi番目のユニットはそれによって、ハッシュテーブル中に存在します見つけ、インサートと同義語チェーンを中心に削除します。頻繁に挿入および欠失の場合にも適用チェーンアドレス法則。
3.ハッシュ次いで
この構造は同時に異なるハッシュ関数の複数である:
こんにちは= RH1(キー)I 1,2、...、K =
ハッシュアドレスのHi = RH1(キー)競合再計算をHI = RH2(キー)......、競合がもはや生成されなくなるまで。この方法は、凝集を発生しにくくなるが、計算時間を増やします。
共通のオーバーフロー領域確立4.
この方法の基本的な考え方である。ハッシュテーブルは、2つの部分、ベーステーブルとオーバーフローテーブル、要素および基本的な紛争の任意のテーブルに分割され、常に移入オーバーフローテーブルの
ハッシュ競合のHashMapのアプローチの
ハッシュマップが表示されハッシュ衝突時に二番目のオプション:チェーンアドレス方式。
コード例:
「国」(国)クラスがあり、我々は、キーと値として、その資本(文字列型)の名前を国オブジェクトを使用します。次の例では、HashMapのは、どのように店がある中で、私たちは、キーと値のペアを理解するのに役立ちます。
パブリック クラス国{ 文字列名。 長期人口; 公共国(文字列名、長い人口){ スーパー(); この .nameの= 名前; この .population = 人口; } パブリック文字列のgetName(){ 戻り名。 } 公共 ボイドのsetName(文字列名){ この .nameの= 名前。 } パブリック ロングgetPopulation(){ 戻り集団。 } パブリック 無効 setPopulation(ロング人口){ この .population = 集団。 } // 国オブジェクト内の名前の長さは、(任意のランダムな31を戻しても、その後の場合 // 番号)と奇数次いでリターン95(任意乱数)場合。 // これは方法以下のようにハッシュコードを生成するための良い練習はありませんが、私は // 良く与えるとハッシュマップの理解を容易にするためにそうします。 @Override 公共 int型のハッシュコード(){ 場合(この .name.length()%2 == 0 ) リターン 31 。 他の 復帰 95 。 } @Override 公共 ブール等しい(オブジェクトobj){ 国他 = (国)OBJ。 もし(name.equalsIgnoreCase((other.name))) を返す 真。 リターン はfalse ; } } パブリック クラスHashMapStructure { 公共 静的 ボイドメイン(文字列[]引数){ 国インド = 新しい国に(「インド」、1000 )。 国日本は = 新しい国( "日本"、10000 ); 国フランス共和国は = 新しい国( "フランス"、2000年); 国ロシア = 新しいです国( "ロシア"、20000 ); HashMapの <国、文字列> countryCapitalMap = 新しい HashMapの<国、文字列> (); countryCapitalMap.put(インド、 "デリー" )。 countryCapitalMap.put(日本、 "東京" )。 countryCapitalMap.put(フランス、 "パリ" ); countryCapitalMap.put(ロシア、 "モスクワ" )。 イテレータ <国> countryCapitalIter = countryCapitalMap.keySet()反復子(); // この行に置かデバッグ点 一方(countryCapitalIter.hasNext()){ 国countryObj = countryCapitalIter.next()。= countryCapitalMap.get(countryObj)。 System.out.println(countryObj.getName() + "----" + 資本); } } }
コメントにデバッグに参加し、構造がcountryCapitalMap時計で見ることができます。
それは、次の図から分かる。
アレイ16のエントリサイズと呼ばれるテーブルがあります。
エントリテーブルアレイメモリオブジェクトクラス。HashMapのクラスは、エントリと呼ばれる内部クラスを持っています。このクラスはインスタンス変数としてエントリキー値が含まれています。私たちが見ていることをエントリクラス構造。エントリ構造クラス:
静的クラスエントリー{のMap.Entryの道具
最終鍵K、
V値、
エントリー次、
最終int型のハッシュ;
... //コードはもっとここに壁紙を行きます
}
1)それらがエントリオブジェクトをインスタンス化するように、キーと値のペアの内部に格納されたハッシュマップまでの時間が、オブジェクトは、上記テーブルのエントリ項目配列に格納されるたびに。今あなたは不思議に思われる必要があり、エントリは(表中の正確な位置に)特定の場所に格納される上に作成されたオブジェクト。答えは、あるキーハッシュコード()メソッド算出されたハッシュ値に応じて(決定します)。キーインデックスエントリアレイ中のハッシュ値を計算するために使用されます。
あなたは15以上の配列インデックスの数字を見れば2)。さて、それはHashMapの$エントリEntryオブジェクトが呼び出されています。
3)私たちは、ハッシュマップのキーと値のペアに4を入れて、それだけで一つの要素のように見えます!!!二つの要素が同じハッシュコードを持っている場合、彼らは同じインデックスに配置されます、ためです。質問はそれを置くためにどのように、発生しますか?これは、ストアにリンクされたリスト(LinkedListの)の形で元の(論理的)です。したがって、それらは15上の位置、およびエントリ、次のリンクの複数のハッシュ値が格納されています。
================================================== ====================
ソリューションの基礎となるHashMapの、およびハッシュ紛争の実装
私たちは、通常使用されるHashMapを持っているが、いくつかは理解していない発生する可能性のあるハッシュの競合は、これらの日、私はそうのように忘れないように、記録し、少し低い理解するためにも、次の情報を回しながら、私たちは、非常に理解していない根本的なHashMapを実現することができます。
図は、直接データ構造にアクセスするためのキーコード値(キー値)に基づいて、(また、ハッシュ・テーブルと呼ばれ、ハッシュテーブル)ハッシュテーブルです。つまり、キー値によってレコードにアクセスするには、テーブルに検索をスピードアップするために位置をマッピングされます。ストレージアレイを記録し、ハッシュ関数と呼ばれるこのマッピング関数は、ハッシュテーブルと呼ばれます。しかし、必然的に、問題が発生します、キーワードの際に比較的大きな数は、これハッシュの衝突という問題を引き起こして、同じアドレスに入射隠さ同じキーワードではありません。それでは、どのようにそれを解決するのですか?
一般的に使用される方法は、一般的にオープンアドレス法である:
ハイ=(H(キー):1.あるアドレッシング + DI)MODのM、iは= 1,2、...、K(K <= M-1)、 前記Hハッシュ関数に(キー)、mはハッシュ・テーブルの長さであり、インクリメントDI配列、次の3つがエミュレートすることができる:
1.1 DI = 1,2,3、...、M-1、プローブ線形再ハッシュ前記;.あなたは空のユニットを見つけるまで、テーブルの次のセルを参照するか、テーブル全体を検索するため。
1.2。ディ= ^ 2 1、 -1 ^ 2,2 ^ 2、-2 ^ 2、⑶^ 2、...、±(K)^ 2、(K <= M / 2) の検出は、前記二次再ハッシュ;テーブルの周りに鳴ってジャンプ。
1.3。ディ=擬似乱数列、及び次いで前記擬似ランダム・ハッシュを検出します。生成された乱数を検出します。
2再ハッシング:あなたは、要素の場所を見つけるまで、ハッシュ衝突は、次ハッシュ関数を使用する時には、格納されていることができれば、ハッシュ関数を複数確立します。
方法3ファスナー(リンクアドレス法):CVは、リスト上の位置の競合があるが、その要素は、衝突の後端のリストに挿入されます
基本的なテーブルとの競合の要素がオーバーフローテーブルに配置され、ベーステーブルとオーバーフローテーブルにハッシュテーブル:4は、共通のオーバーフロー領域を確立します。
HashMapの根本的なリストには、ファスナー法上にあるアレイと実装です。インデックスは、上記されたときに挿入し、配列のインデックスに対応するキーのハッシュ値に基づいて計算されるが、インデックス=ハッシュコード%のtable.length、(添字は、上記バケットである)として計算した第一、それは要素のリストを形成するときに存在しない要素が標準より上に存在しない場合、要素が直接位置に、後端にその要素を挿入します。
クエリは、同じことが第一のハッシュキーに基づいて、対応する指数を計算し、上記のこのインデックスの多くの要素がある場合は、その後、対応する位置を見つけるためにする場合は、あなたがこのリストに対応を見つけるまで、見つける必要があります要素。