HASHについての補足-HASH関数の方法とHASHテーブルの長さを制御して競合を解決するいくつかの方法

序文:

HASHテーブル、特にHASN関数の構築は私には本当に理解できません...

また、HASNについてお話したいとの声もありましたので、もう一点自習したいと思います。

ハッシュ表

ハッシュテーブルは主に検索用であり、メモリ内のデータを効率的かつ迅速に検索するための検索時間の複雑さはO(1)です。

ハッシュテーブルを構築するための3つのキーがあります:ハッシュテーブルの長さを制御する方法をどのようにハッシュ関数を設計すると、どのようにハッシュの競合に対処します

ハッシュテーブルの長さを制御する方法

HASHテーブルの長さは一般的に固定されています。データを保存する前に、データが保存される大きさを把握し、HASHテーブルが頻繁に拡張されないようにする必要があります。

ただし、設計が大きすぎると、現在のデータスケールを格納するためにそれほど多くのスペースを必要としないため、スペースが無駄になります。

デザインが小さすぎると、HASHの競合が発生しやすくなり、HASHテーブルの効率が反映されません。

したがって、設計するHASHテーブルのサイズは、HASHの競合を可能な限り減らし、スペースをできるだけ無駄にしないようにする必要があります。適切なHASHテーブルのサイズを選択することが、HASHテーブルのパフォーマンスを向上させるための鍵となります。

HASH関数を選択するとき、残りの方法を分割してそのままにすることを選択することがよくあります。つまり、格納されたデータのキー値をHASHテーブルの全長で除算し、得られる残りはそのHASH値です。

常識では、数値を素数で割ると、最も分散した残りが生成されると言われています。通常、テーブルのサイズを使用して、HASH関数の結果に対してモジュロ演算を実行するため、

テーブルのサイズが素数の場合、可能な限り分散したHAHS値を生成します。

HASHテーブルのもう1つの概念は、充填率です。その式とプロパティについては詳しく説明しません。

そのような概念がある理由については、HASHテーブルにインストールするデータが多いほど、HASHの競合が発生する可能性が高いと理解しています。

HASHテーブルがいっぱいになり、1つの添え字しか挿入できない場合、この時点でHASHテーブルにデータを挿入する必要があるため、挿入効率がO(n)レベルに達する可能性があります。

保存できる場所を見つけるために、HASHテーブル全体をトラバースする必要もあります。

通常、私たちが焦点を当てているのは、HASHテーブルの平均ルックアップ長を最小化し、平均ルックアップ長がO(1)時間の複雑さであることを確認することです。

充填率aの値が小さいほど、競合の可能性は低くなりますが、小さすぎないようにする必要があるため、スペースの浪費が大きくなります。

私たちは取る場合は0.1 0.10 1、ハッシュ・テーブルの長さは、100 1001 0 0、我々は唯一のインストール10 101 0キー値キーのキーK E Yペアは保存されているものよりも少なく、拡張にはHASHテーブルが必要ですが、残りの90キー-キーキーkは電子yは実際にスペースの無駄です。

通常の状況では、aが適切である限り(通常は0.7から0.8の間)、ハッシュテーブルの平均ルックアップ長は一定であり、これはO(1)レベルです。

要約すると、可能な限り効率的なHASHテーブルサイズを構築する方法は次のとおりです。

·确保哈希表长度是一个素数,这样会产生最分散的余数,尽可能减少哈希冲突

·设计好哈希表装填因子,一般控制在0.7-0.8

·确认我们的数据规模,如果确认了数据规模,可以将数据规模除以装填因子,根据这个结果来寻找一个可行的哈希表大小

·当数据规模会动态变化,不确定的时候,这个时候我们也需要能够根据数据规模的变化来动态给我们的哈希表扩容,
 所以一开始需要自己确定一个哈希表的大小作为基数,然后在此基础上达到装填因子规模时对哈希表进行扩容。

HASH関数(文字列HASH)

ハッシュ関数は、保存されたデータのハッシュ値を計算するために使用されます。保存されたデータのタイプに応じて、さまざまなハッシュ関数を設計できます。

Guo先生は、優れたHASH関数を構築することで、競合を減らし、検索を高速化できると述べました。

一般に、文字列HASHは通常次の式に属します。

HASH值 = 计算后的存储值 / HASH表的大小

格納されている数値が整数の場合は、まったく計算する必要はなく、上記の式で計算した後、格納されている値として整数値を直接使用します。

次に、一般的な文字列ハッシュアルゴリズムについて説明する例として文字列を取り上げます。他のタイプのデータでも、同様のアイデアを使用して独自のHASHアルゴリズムを設計できます。

たとえば、固定値PPを取りますP、文字列をPPとして扱いますPのベース番号、および各文字を表すために0より大きい値を割り当てます。一般的に、割り当てられた値はPP未満ですP

たとえば、小文字で構成される文字列の場合、最初に考える必要があるのはASCLL ASCLLA S C L Lコード、この小文字を入力ASCLL ASCLL割り当てるA S C L Lのそれにコードを。

固定値Mを取り、この文字列のハッシュ値として、MまでのPベース番号の残りを見つけます。

HASH関数を構築する他の方法については、PPTを見てください。

競合を解決する方法

序文:

タオ・リユ先輩の話にショックを受けました。以下をご覧ください。

HASHの競合を解決する理由HASHの競合を解決しない場合にのみ遅くなりますHASHの競合を解決する理由解決されない場合は遅くなるだけです である、それはすべき必見H A S Hチョンの競合何の解決には決めていない、それはちょうどしまう遅くイーディアンをし、持っています

ここに写真の説明を挿入

開発アドレス指定方法:

この方法は理解しやすい、つまりH i HiH iはループを続け、適切な場所を見つけてからロードします。

増分diには、次の3つの値を指定できます。

线性取值,1,2,3....这样,也就是从冲突位置不断往后找下一个可以存放的下标

二次取值,1,4,9....这样,也就是从冲突位置不断往后找x的二次方的下标,其中x从1开始线性增大

随机取值,di可以去任意随机值,随机找一个。

同じ方法は時間がかかり、要素を削除することはできません。

次にHASHメソッド:

私たち全員が単語の別の意味を知っているので、最初のものが完全にハッシュではない場合

競合を解決するには、別の競合を作成します。

次にHASHバケット)-ジッパー方式:(ここで借りたアイデアと写真を借りる)

各添え字はリンクリストに保存され、同じハッシュ値を持つキーが添え字のリンクリストの直後に挿入されます。

ここに写真の説明を挿入

この方法の特徴は、テーブルのサイズが格納されているデータの量とほぼ同じであるということです(大したことではなく、各添え字に1つのノードのみが配置されます。添え字が同じ場合、同じ添え字のリンクリストに配置され、新しい添え字を占有しません。 )、

したがって、ハッシュバケット方式は特に負荷率に依存しません。ハッシュテーブルブロックがいっぱいになっても効率が向上するため、アドレス指定方式の開発では負荷率を確保する必要があります。

もちろん、ハッシュバケット方式は万能薬ではなく、次のような欠点もあります。

次のノードへのポインタもあるため、要素を格納するためにもう少しスペースが必要です。

また、要素に直接アクセスするのではなく、間接的にポインタを参照する必要があるため、各検出にはさらに時間がかかります。

しかし実際には、上記の欠点は現在のコンピューターにあまり影響を与えないため、これらの欠点は重要ではありません。したがって、ハッシュの実際の使用では、ハッシュバケットは一般に競合を解決するために使用されます。

ハッシュテーブルでこのリンクリストを無限に長くすることはできないことに注意してください。

たとえば、すべてのデータのハッシュ値が同じである場合、添え字は1つだけになり、他の添え字は使用されないため、極端な状況が発生します。

この場合、それを見つけたいのであれば、リンクされたリストで検索するのと同じです。検索効率はO(n)であり、ハッシュテーブルの設計の考え方に明らかに違反しています。

したがって、特定のリンクリストまたは複数のリンクリストの長さが特定の長さに達した場合、ハッシュテーブルを展開する必要があります。具体的な詳細は、設計方法によって異なります。

ただし、開発アドレッシング方式と比較すると、開発アドレッシング方式も独自の充填率を確保する必要があるため、拡張の頻度がはるかに少なく、より頻繁に拡張されます。

したがって、効率の点では、ジッパー方式は開発アドレス指定方式よりも優れています。

おすすめ

転載: blog.csdn.net/C202207LYX/article/details/107847293