ハッシュテーブルは本当にO(1)になるのでしょうか?


114

ハッシュテーブルがO(1)を達成できることは一般的な知識のようですが、それは私には意味がありませんでした。誰かがそれを説明できますか?頭に浮かぶ2つの状況を次に示します。

A. 値は、ハッシュテーブルのサイズよりも小さいintです。したがって、値は独自のハッシュであるため、ハッシュテーブルはありません。しかし、あったとしても、それはO(1)であり、それでも非効率的です。

B. 値のハッシュを計算する必要があります。この状況では、検索されるデータのサイズの順序はO(n)です。O(n)の作業を行った後、ルックアップはO(1)になるかもしれませんが、それでも私の目にはO(n)が出てきます。

また、完全なハッシュテーブルまたは大きなハッシュテーブルがない限り、バケットごとに複数のアイテムが存在する可能性があります。したがって、いずれにしても、ある時点で小さな線形検索に発展します。

ハッシュテーブルはすばらしいと思いますが、理論的なものでない限り、O(1)の指定はありません。

ウィキペディアのハッシュテーブルに関する記事は、常に一定のルックアップ時間を参照しており、ハッシュ関数のコストを完全に無視しています。それは本当に公正な措置ですか?


編集:私が学んだことを要約するには:

  • ハッシュ関数はキーのすべての情報を使用する必要がないため、一定の時間になる可能性があり、十分に大きいテーブルは衝突を一定の時間に近づけることができるため、技術的には正しいです。

  • ハッシュ関数とテーブルサイズが衝突を最小限に抑えるように選択されている限り、一定の時間のハッシュ関数を使用しないことがよくあるので、時間が経つとうまくいきます。


31
O(1)ではなく、償却済みのO(1)です。
kennytm

O()は多数の操作の制限であることを忘れないでください。「平均」では、衝突が多くなることはありません。個々の操作で衝突が発生する必要はありません。
マーティンベケット

文字列の実装によっては、文字列はハッシュ値を持ち運ぶ場合があるため、これは一定です。ポイントは、ハッシュルックアップの複雑さとは無関係です。
リッチレマー2014

@kennytmもちろん、入力をハッシュした後のルックアップは償却されたO(1)です。しかし、ハッシュを計算するコストは本当に無視できますか?文字列、つまり文字配列をハッシュしているとします。ハッシュを生成するために、各文字が繰り返されるため、文字列のハッシュはO(N)であり、Nは文字列の長さです。これがC#用にドキュメント化hashCode()された方法であり、Javaのメソッドがのために実装された方法ですStringgrepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/...
spaaarky21

1
@ spaaarky21話しているO(N)のNは文字列の長さであり、ハッシュテーブルのサイズとは異なります。マーク・バイヤーの答えはすでにこれに対処しました。
kennytm 2017年

回答:


65

ここには、mとnの2つの変数があります。mは入力の長さ、nはハッシュ内の項目の数です。

O(1)ルックアップパフォーマンスクレームは、少なくとも2つの仮定を行います。

  • オブジェクトは、O(1)時間で比較して同等である可能性があります。
  • ハッシュの衝突はほとんどありません。

オブジェクトが可変サイズであり、等価性チェックですべてのビットを調べる必要がある場合、パフォーマンスはO(m)になります。ただし、ハッシュ関数はO(m)である必要はありません。O(1)でもかまいません。暗号化ハッシュとは異なり、辞書で使用するハッシュ関数は、ハッシュを計算するために入力のすべてのビットを調べる必要はありません。実装では、固定数のビットのみを自由に参照できます。

アイテムが十分に多い場合、アイテムの数は可能なハッシュの数よりも多くなり、衝突が発生してO(1)を超えるパフォーマンスの上昇を引き起こします。たとえば、単純なリンクリストトラバーサルのO(n)(またはO(n) * m)両方の仮定が偽の場合)。

実際には、O(1)の主張は技術的には偽ですが、多くの現実世界の状況、特に上記の仮定が当てはまる状況ではほぼ当てはまります。


4
上記と同様に、ハッシュを一度計算した後、不変オブジェクトをキーとして使用している場合(Java文字列など)、それを覚えておけば、再度計算する必要はありません。一方、正しいバケットを見つけたら、通常はハッシュを使用して2つのキーが等しいかどうかを判断することはできないため、文字列の場合、O(m)トラバーサルを実行して、それらが等しいかどうかを確認する必要があります。
JeremyP 2010

1
@JeremyP:O(m)の等値比較の良い点。見逃しました-更新された投稿。ありがとう!
Mark Byers、

2
sや機械語に収まる何かをO(1)ハッシュしている場合、この主張は真実ですint。これが、ハッシュに関するほとんどの理論が想定していることです。
Thomas Ahle 2014年

私はあなたのマークの説明が好きです、meshfields.de / hash
Steve K

3
では、「mは入力の長さがある」 - 入力は、それが挿入されているすべてのキー&値を意味するかもしれませんが、それはあなたが意味(少なくとも、すでに話題を理解している人に)後に明らかになった-あまりに漠然としているキーを。明確にするために、回答で「キー」の使用を提案するだけです。ところで、具体的な例-Visual C ++のstd::hashテキストキーは、テキストに沿って等間隔に配置された10文字をハッシュ値に結合しているため、テキストの長さに関係なくO(1)です(ただし、GCCよりも衝突が発生しやすくなります)。これとは別に、O(1)の主張には、mnよりはるかに小さいという(通常は正しく)別の仮定があります。
トニー・デルロイ

22

ハッシュを計算する必要があるため、検索されるデータのサイズの順序はO(n)です。O(n)の作業を行った後、ルックアップはO(1)になるかもしれませんが、それでも私の目にはO(n)が出てきます。

何?単一の要素をハッシュするには一定の時間がかかります。なぜそれが他にあるのでしょうか?n要素を挿入する場合は、はい、nハッシュを計算する必要があります。これには線形時間がかかります...要素を検索するには、探しているものの単一のハッシュを計算し、それを使用して適切なバケットを見つけます。ハッシュテーブルに既にあるすべてのハッシュを再計算する必要はありません。

そして、完全なハッシュまたは大きなハッシュテーブルがない限り、バケットごとにいくつかのアイテムがあるため、いずれにしても、それは小さな線形検索に展開されます。

必ずしも。バケットは必ずしもリストまたは配列である必要はありません。それらは、バランスのとれたBSTなど、任意のコンテナータイプにすることができます。それはO(log n)最悪の場合を意味します。しかし、このため、1つのバケットに多くの要素を入れすぎないように、適切なハッシュ関数を選択することが重要です。KennyTMが指摘したように、平均的には、O(1)たまにバケットを掘る必要がある場合でも、まだ時間はあります。

ハッシュテーブルのトレードオフは、もちろんスペースの複雑さです。あなたは時間とスペースを交換しています。これはコンピューティングサイエンスの通常のケースのようです。


他のコメントの1つで、文字列をキーとして使用することについて言及しています。文字列は複数の文字で構成されているため、文字列のハッシュを計算するのにかかる時間を心配していますか?他の誰かが再び指摘したように、ハッシュを計算するために必ずしもすべての文字を調べる必要はありませんが、そうした方がより良いハッシュを生成する可能性があります。その場合、mキーに平均文字があり、それらすべてを使用してハッシュを計算した場合、私はあなたが正しいと思いますが、その検索にはが必要O(m)です。それならm >> n問題があるかもしれません。その場合は、おそらくBSTの方が良いでしょう。または、より安価なハッシュ関数を選択します。


ハッシュテーブルはBSTを使用しません。BSTはハッシュ値を必要としません。ただし、マップとセットはBSTとして実装できます。
Nick Dandoulakis

3
@ニック:え?いいえ... BSTはハッシュ値を必要としません...それがポイントです。この時点では既に衝突(同じハッシュ...または少なくとも同じバケット)があると想定しているため、適切な要素、つまり実際の値を見つけるために別のものを調べる必要があります。
mpen

おお、私はあなたの要点を理解しています。しかし、私はBSTとハッシュを混ぜることが問題に値するかどうかはわかりません。BSTを使用しないのはなぜですか?
Nick Dandoulakis、

2
私はあなたO(n)衝突のためにそれを取り除くことができると言っているだけです。多くの衝突予想される場合、その通りです。おそらく、そもそもBSTを使用するほうがよいでしょう。
mpen

1
@ spaaarky21 Nそうですが、その場合は文字列の長さです。1つの文字列をハッシュするだけで、どの「バケット」に入れる必要があるかを判別できます。ハッシュマップの長さによって大きくなることはありません。
mpen 2017年

5

ハッシュは固定サイズです。適切なハッシュバケットを検索することは、固定コストの操作です。これは、O(1)であることを意味します。

ハッシュの計算は、特にコストのかかる操作である必要はありません。ここでは、暗号化ハッシュ関数については触れていません。しかし、それはby byによるものです。ハッシュ関数の計算自体は、要素の数nに依存しません。要素内のデータのサイズに依存する可能性がありますが、これはnが参照するものではありません。したがって、ハッシュの計算はnに依存せず、O(1)でもあります。


3
ハッシュバケットの検索はO(1)です。しかし、正しいキーを見つけるのはO(n)プロシージャで、nはハッシュの衝突の数に依存します。
Nick Dandoulakis

1
つまり、3つのステップで、ハッシュを計算し、バケットを見つけ、バケットを検索します。中央のステップは定数ですか バケットの検索は通常一定です。ハッシュの計算は通常、バケットを見つける他の方法よりも数桁安価です。しかし、それは本当に一定の時間になるでしょうか?素朴な部分文字列検索では、2つの長さに対してO(n * m)と言うので、なぜここではキーの長さが無視されるのですか?
抽選

固定長のキーを見つけることは、そのリストが裏付けられている場合にのみO(n)であり、平衡型ツリーが裏付けられたハッシュテーブルはO(log(n))
jkになります。

良いハッシュ関数の場合@Jkは、最悪の場合は常にlogn、で私の答えを参照してくださいstackoverflow.com/questions/4553624/hashmap-get-put-complexity/...
トーマスAhle

最悪の場合、衝突の場合の複雑さはo(n)になります
Saurabh Chandra Patel

3

テーブルにキーの数が一定であり、他のいくつかの仮定が行われている場合にのみ、ハッシュはO(1)です。しかし、そのような場合には利点があります。

キーにnビット表現がある場合、ハッシュ関数はこれらのビットの1、2、... nを使用できます。1ビットを使用するハッシュ関数について考えます。確かに評価はO(1)です。ただし、キースペースを2に分割するだけです。したがって、2 ^(n-1)ものキーを同じビンにマッピングします。BST検索を使用すると、ほぼ満杯の場合、特定のキーを見つけるのに最大n-1ステップかかります。

これを拡張して、ハッシュ関数がKビットを使用する場合、ビンサイズが2 ^(nk)であることを確認できます。

したがって、Kビットハッシュ関数==> 2 ^ K以下の有効なビン==>ビンあたり2 ^(nK)までのnビットキー==>(nK)ステップ(BST)で衝突を解決します。実際、ほとんどのハッシュ関数は「効果的」ではなく、2 ^ kのビンを生成するためにKビット以上必要/使用します。したがって、これも楽観的です。

このように表示できます。最悪の場合、nビットのキーのペアを一意に区別できるようにするために、〜nステップが必要になります。この情報理論の制限、ハッシュテーブルかどうかを回避する方法は本当にありません。

ただし、これはハッシュテーブルをどのように/いつ使用するかではありません。

複雑さの分析では、nビットキーの場合、テーブルにO(2 ^ n)キーを含めることができると想定しています(たとえば、すべての可能なキーの1/4)。しかし、ハッシュテーブルを常に使用しているわけではありませんが、ほとんどの場合、テーブルには一定数のnビットキーしかありません。テーブルに一定数のキーのみが必要な場合、たとえばCが最大数である場合、O(C)ビンのハッシュテーブルを形成し、予想される一定の衝突を保証できます(適切なハッシュ関数を使用)。キーのnビットの〜logCを使用するハッシュ関数。次に、すべてのクエリはO(logC)= O(1)です。これは、人々が「ハッシュテーブルアクセスはO(1)である」と主張する方法です/

ここにはいくつかの落とし穴があります。まず、すべてのビットが必要なわけではないと言うのは、請求のトリックにすぎない場合があります。最初に、ハッシュ関数にキー値を渡すことはできません。これは、メモリ内のO(n)のnビットを移動するためです。したがって、たとえば参照渡しを行う必要があります。しかし、それでもO(n)操作であるどこかにそれを保存する必要があります。あなたはそれをハッシュに請求しないだけです。計算タスク全体でこれを回避することはできません。次に、ハッシュを実行し、ビンを見つけ、複数のキーを見つけました。コストは解決方法に依存します-比較ベース(BSTまたはリスト)を実行する場合、O(n)操作が必要になります(リコールキーはnビットです)。2番目のハッシュを実行すると、2番目のハッシュが衝突した場合にも同じ問題が発生します。

この場合は、BSTなどの代替案を検討してください。Cキーがあるため、バランスのとれたBSTの深さはO(logC)になるため、検索ではO(logC)ステップがかかります。ただし、この場合の比較はO(n)演算になるため、この場合はハッシュの方が適しているようです。


1

TL; DR:O(1)ハッシュ関数のユニバーサルファミリーからランダムにランダムにハッシュ関数を選択した場合、ハッシュテーブルは予想される最悪の場合の時間を保証します。予想される最悪のケースは平均的なケースと同じではありません。

免責事項:私はO(1)、ハッシュテーブルがであることを正式には証明していません。そのため、コースラ[ 1 ]のこのビデオをご覧ください。私はまた、償却された、ハッシュテーブルの面。これは、ハッシュと衝突についての議論に直交しています。

他の回答やコメントでこのトピックに関する驚くほど多くの混乱が見られますが、この長い回答でそれらのいくつかを修正しようとしています。

最悪のケースについての推論

ワーストケース分析にはさまざまなタイプがあります。これまでのところ、ほとんどの回答がこれまでに行った分析は、最悪のケースではなく、平均的なケースです [ 2 ]。平均的なケース分析の方が実用的です。多分あなたのアルゴリズムには悪い最悪の場合の入力が1つありますが、実際には他のすべての可能な入力に対してうまく機能します。結論は、ランタイム実行しているデータセットに依存するということです。

getハッシュテーブルのメソッドの次の疑似コードを考えます。ここでは、連鎖によって衝突を処理することを想定しているため、テーブルの各エントリは、リンクされた(key,value)ペアのリストです。また、バケットの数mは固定されていると仮定します。O(n)ただしn、は入力の要素数です。

function get(a: Table with m buckets, k: Key being looked up)
  bucket <- compute hash(k) modulo m
  for each (key,value) in a[bucket]
    return value if k == key
  return not_found

他の回答が指摘しているように、これは平均O(1)して最悪のケースで実行されO(n)ます。ここで挑戦することで証明の小さなスケッチを作ることができます。課題は次のとおりです。

(1)ハッシュテーブルアルゴリズムを敵に渡します。

(2)敵はそれを研究し、彼が望む限り準備することができます。

(3)最後に、敵はあなたnにあなたのテーブルに挿入するためのサイズの入力を与えます。

問題は次のとおりです。あなたのハッシュテーブルは敵の入力でどれくらい速いですか?

ステップ(1)から、攻撃者はハッシュ関数を知っています。ステップ(2)の間に、敵対者は、例えば要素の束のハッシュをランダムに計算することによりn、同じ要素を持つ要素のリストを作成できhash modulo mます。そして(3)で彼らはあなたにそのリストを与えることができます。しかし、驚いたことに、すべてのn要素が同じバケットにハッシュされるため、アルゴリズムはO(n)そのバケット内のリンクされたリストをトラバースするのに時間がかかります。何度チャレンジを試みても、敵は常に勝利しますO(n)。それが、最悪の場合、アルゴリズムがどれほど悪いかです。

ハッシュはO(1)になるのはなぜですか?

以前の課題で私たちを驚かせたのは、攻撃者がハッシュ関数を非常によく知っていて、その知識を使用して最悪の可能な入力を作成できることでした。常に1つの固定ハッシュ関数を使用する代わりにH、実行時にアルゴリズムがランダムに選択できる一連のハッシュ関数が実際にあるとしたらどうでしょうか。気になる人のために、ハッシュ関数のユニバーサルファミリHと呼ばれています [ 3 ]。さて、これにランダム性を追加してみましょう。

まず、当社のハッシュテーブルはまた、種子を含んと仮定rし、r構築時にランダムな番号に割り当てられています。一度割り当てると、そのハッシュテーブルインスタンスに対して固定されます。今度は、疑似コードをもう一度見てみましょう。

function get(a: Table with m buckets and seed r, k: Key being looked up)
  rHash <- H[r]
  bucket <- compute rHash(k) modulo m
  for each (key,value) in a[bucket]
    return value if k == key
  return not_found

もう一度チャレンジしてみると、ステップ(1)から、攻撃者はのすべてのハッシュ関数を知ることができますがH、使用する特定のハッシュ関数はに依存していrます。の値rは私たちの構造にプライベートであり、攻撃者は実行時にそれを検査することも、事前に予測することもできないため、私たちにとって常に悪いリストを作成することはできません。ステップ(2)でランダムに1つの関数hashを選択した攻撃者がH、でn衝突のリストhash modulo mを作成し、ステップ(3)でそれを送信H[r]すると、実行時hashに選択したものと同じになるように指を交差するとします。

これは敵対者にとって深刻な賭けです。彼が作成したリストはで衝突しhashますが、の他のハッシュ関数ではランダム入力になりHます。彼がこの賭けに勝った場合、ランタイムはO(n)以前と同様に最悪のケースになりますが、負けた場合、平均O(1)時間をとるランダムな入力が与えられるだけです。そして実際、ほとんどの場合、敵は負け、|H|挑戦ごとに一度だけ勝ち、私たちは|H|非常に大きくすることができます。

この結果を、敵が常に挑戦に勝った以前のアルゴリズムと比較してください。ここで少し手を振っていますが、ほとんどの場合、敵対者は失敗し、これは敵対者が試すことができるすべての可能な戦略に当てはまるため、最悪のケースはですO(n)が、予想される最悪のケースは実際O(1)です。


繰り返しますが、これは正式な証明ではありません。この予想される最悪のケースの分析から得られる保証は、ランタイムが特定の入力から独立していることです。これは真にランダムな保証であり、意欲的な敵が悪い入力を簡単に作成できることを示した平均的なケース分析とは対照的です。


0

O(1)の最悪の場合の時間を取得できる設定は2つあります。

  1. 設定が静的な場合、FKSハッシュにより、最悪の場合のO(1)保証が得られます。しかし、あなたが示したように、あなたの設定は静的ではありません。
  2. あなたはカッコウのハッシュを使用する場合は、照会および削除があるO(1) 最悪の場合、しかし、挿入があるだけでO(1)期待されます。挿入の総数に上限があり、テーブルサイズを約25%大きく設定すると、カッコウハッシュは非常にうまく機能します。

ここからコピー


0

ここでの議論に基づいて、Xが(テーブル内の要素の数/ビンの数)の上限である場合、ビンルックアップの効率的な実装を想定したO(log(X))がより良い答えであると思われます。


0

A.値は、ハッシュテーブルのサイズよりも小さいintです。したがって、値は独自のハッシュであるため、ハッシュテーブルはありません。しかし、あったとしてもO(1)であり、それでも非効率的です。

これは、キーを個別のバケットに簡単にマッピングできる場合なので、配列はハッシュテーブルよりもデータ構造の選択として適しているようです。それでも、非効率性はテーブルのサイズによって大きくなりません。

(プログラムの進化に伴ってintがテーブルサイズよりも小さいままであると信頼できない場合、その関係が成立しない場合にコードを再利用できるようにする場合、または単にハッシュテーブルを使用しない場合は、ハッシュテーブルを使用する可能性があります。コードを読んだり保守したりする人に、関係を理解し​​て維持するために精神的な努力を無駄にする必要があります)。

B.値のハッシュを計算する必要があります。この状況では、検索されるデータのサイズの順序はO(n)です。O(n)の作業を行った後、ルックアップはO(1)になる可能性がありますが、それでも私の目にはO(n)が含まれています。

キーのサイズ(バイトなど)とハッシュテーブルに格納されているキーの数のサイズを区別する必要があります。ハッシュテーブルがO(1)操作を提供するという主張は、キーの数が数百から数千に、数百万から数十億に増加しても、操作(挿入/消去/検索)がさらに遅くなる傾向がないことを意味します少なくともすべてのデータがRAMまたはディスクであっても、同等の高速ストレージでアクセス/更新されます-キャッシュの影響が出てくる可能性がありますが、最悪の場合のキャッシュミスのコストでさえ、ベストケースヒットの定数倍になる傾向があります)。

電話帳について考えてみましょう。かなり長い名前があるかもしれませんが、その本の名前が100であろうと1000万であろうと、平均的な名前の長さはかなり一貫しており、歴史上最悪のケースです...

ギネス世界記録は、これまで誰もが使用した最長の名前であり、アドルフブレインチャールズデイビッドアールフレデリックジェラルドヒュ​​ーバートアービンジョンケネスロイドマーティンネロオリバーポールクインシーランドルフシャーマントーマスアンキャスビクターウィリアムセルクセスヤンシーウォルフシュレゲルシュタインハウゼンベルグドルフ、シニア

... wc215文字だと私に語った-それはありませんハードキーの長さに上限が、私たちはそこにあることについて心配する必要はありません大規模以上。

これは、ほとんどの実際のハッシュテーブルに当てはまります。キーの平均の長さは、使用中のキーの数に応じて大きくなる傾向はありません。例外があります。たとえば、キー作成ルーチンは、増加する整数を埋め込んだ文字列を返す可能性がありますが、それでも、キーの数を1桁増やすたびに、キーの長さを1文字だけ増やすだけで、重要ではありません。

また、固定サイズのキーデータからハッシュを作成することもできます。たとえば、MicrosoftのVisual C ++には、標準ライブラリの実装が同梱std::hash<std::string>されており、文字列に沿って等間隔に配置された10バイトだけを組み込んだハッシュを作成するため、文字列が他のインデックスでしか変化しない場合は、衝突(したがって、実際にはO(1)以外の動作)が発生します。衝突後の検索側)ですが、ハッシュを作成する時間には厳しい上限があります。

また、完全なハッシュテーブルまたは大きなハッシュテーブルがない限り、バケットごとに複数のアイテムが存在する可能性があります。したがって、いずれにしても、ある時点で小さな線形検索に発展します。

一般的には真実ですが、ハッシュテーブルのすばらしい点は、これらの「小さな線形検索」中にアクセスされるキーの数が- 衝突への個別の連鎖アプローチの場合-ハッシュテーブルの負荷係数(バケットに対するキーの比率)の関数であることです。

たとえば、負荷係数が1.0の場合、キーの数に関係なく、これらの線形検索の長さは平均で約1.58です(ここで私の回答を参照)。以下のために閉じられたハッシュにはもう少し複雑だが、あまり悪化し、負荷率があまり高くない場合。

ハッシュ関数はキーのすべての情報を使用する必要がないため、一定の時間になる可能性があり、十分に大きいテーブルは衝突を一定の時間に近づけることができるため、技術的には正しいです。

この種は要点を逃しています。あらゆる種類の連想データ構造は、最終的にはキーのすべての部分にわたって操作を行わなければならない場合があります(不等式はキーの一部のみから決定される場合がありますが、等式は一般にすべてのビットを考慮する必要があります)。最低でも、キーを1回ハッシュしてハッシュ値を格納でき、64ビットMD5などの十分に強力なハッシュ関数を使用している場合、2つのキーが同じ値にハッシュされる可能性(会社私が働いていたのは、分散データベースの場合とまったく同じでした。ハッシュ生成時間は、WAN全体のネットワーク伝送と比較して、まだわずかでした)。したがって、キーを処理するためのコストにこだわる必要はあまりありません。それは、データ構造に関係なくキーを格納することに固有であり、前述のとおり、そうではありません。

十分な大きさのハッシュテーブルが衝突を引き起こすので、それも要点を逃しています。個別のチェーンでは、任意の負荷係数で一定の平均衝突チェーン長がまだあります-負荷係数が高い場合、それはちょうど高く、その関係は非線形です。SOユーザーHans も私の回答にコメントしおりその上にもリンクさています

空でないバケットを条件とする平均バケット長は、効率のより良い測定値です。a /(1-e ^ {-a})です[aは負荷係数、eは2.71828 ...]

したがって、負荷係数だけで、挿入/消去/検索操作中に検索する必要がある衝突するキーの平均数が決まります。個別のチェーンでは、負荷係数が低いときに一定に近づくだけでなく、常に一定です。主張にはある程度の有効性がありますが、オープンアドレス指定の場合:競合する要素の一部が代替バケットにリダイレクトされ、他のキーの操作に干渉する可能性があるため、高い負荷係数(特に> .8または.9)では、衝突チェーンの長さがさらに劇的に悪化します。

ハッシュ関数とテーブルサイズが衝突を最小限に抑えるように選択されている限り、一定の時間のハッシュ関数を使用しないことがよくあるので、時間が経つとうまくいきます。

まあ、テーブルのサイズは、厳密なハッシュまたは個別のチェーンの選択を考慮して、まともな負荷係数になるはずですが、ハッシュ関数が少し弱く、キーがあまりランダムではない場合、素数のバケットを使用すると、多くの場合、削減に役立ちます衝突も(hash-value % table-sizeハッシュ値の高位ビットまたは2つだけが変更されても、ハッシュテーブルのさまざまな部分に疑似ランダムに広がるバケットに解決されるようにラップされます)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.