(いつ)ハッシュテーブルルックアップはO(1)ですか?


71

ハッシュテーブルルックアップは一定の時間で動作するとよく言われます。ハッシュ値を計算すると、配列ルックアップのインデックスが得られます。しかし、これは衝突を無視します。最悪の場合、すべてのアイテムが同じバケットに到着し、ルックアップ時間は線形()になります。Θn

ハッシュテーブルルックアップを本当にすることができるデータの条件はありますか?それは平均的にのみですか、またはハッシュテーブルにO 1 最悪のケースルックアップを含めることができますか?O1O1

注:ここではプログラマーの視点から来ています。ハッシュテーブルにデータを格納すると、ほとんど常に文字列またはいくつかの複合データ構造であり、データはハッシュテーブルの有効期間中に変更されます。したがって、完璧なハッシュについての答えはありがたいですが、それらはかわいいですが、逸話的であり、私の観点からは実用的ではありません。

PSフォローアップ:ハッシュテーブル操作O(1)はどのようなデータですか?


3
償却アクセス時間で生活できますか?一般に、ハッシュテーブルのパフォーマンスは、許容できるスパースハッシュテーブルのオーバーヘッドと実際のハッシュ値の分散方法に大きく依存します。O(1
ラファエル

5
ああ、ところで:リストの代わりに(バランスのとれた)検索ツリーを使用すると、線形の最悪の場合の動作を回避できます。
ラファエル

1
@Raphael私は、償却されたときとそうでないときを広い線に沿って)説明する答えに非常に興味があります。ハッシュ値の配布方法については、それが私の質問の一部です。どうすればわかりますか?ハッシュ関数は値をうまく分配するはずだと知っています。しかし、彼らが常に最悪の場合に到達した場合、それは意味をなさないでしょう。O(1
ジル

1
時期尚早な最適化にも注意してください。小さい(数千要素)データの場合、オーバーヘッドが低いため、バランスの取れたバイナリツリーがハッシュテーブルよりも優れていることがよくあります(文字列の比較は文字列のハッシュよりもはるかに安価です)。Oログn
isturdy

回答:


41

最悪の場合の時間を取得できる2つの設定があります。O1

  1. 設定が静的な場合、FKSハッシュにより最悪の場合の保証が得られます。しかし、あなたが示したように、設定は静的ではありません。O1

  2. Cuckooハッシュを使用する場合、クエリと削除は最悪の場合ですが、挿入はO 1 のみが予想されます。カッコウのハッシュは、挿入の総数に上限があり、テーブルサイズを約25%大きく設定すると非常にうまく機能します。O1O1

ここに詳細情報があります


3
FKSとCuckooについて詳しく教えてください。両方の用語は私にとって新しいものです。
ジル

1
動的完全ハッシュはどうですか?それは持っている最悪の場合の検索及びOは、1 の挿入や削除を償却しました。(citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.30.8165O1O1
ジョー

2
FKSは(Fredman、Komlós、Szemerédi)のイニシャルであり、Cuckooは種の名前です。カッコウのヒナがシビリングの卵を巣から押し出すため、このタイプのハッシングに使用されます。これは、このメソッドを持つメソッドの機能に多少似ています。
ウリ

1
@シュレシュ:本当に?依存しない関数が必要だと思いましたが、これは常にエキスパンダーの必要性に関連付けられていました。私は訂正します。コメントを少し削除します。ログn
ルイス

1
@Sureshが指摘しているように、この答えについてより有用なコメントをするために、カッコウハッシュは理論的に分析するために使用される派手な(そして大きな)ハッシュ関数なしでうまく機能します。
ルイス

21

この回答では、TAoCP Vol 3、Ch 6.4の一部を要約しています。

我々は、値のセットがあると仮定N我々は、アレイに格納したいのAサイズのM。ハッシュ関数hを使用しますV [ 0 .. M ; 一般的に、M « | V | α = nと呼ぶVnAmh:V[0..M)M|V|負荷率Aを。ここでは、自然なm=Mを仮定します。実用的なシナリオでは、我々は持っているメートルの«Mは、しかし、とまでマッピングする必要がありメートル自分自身を。α=nmAm=MmMm

最初の観測は、が均一な特性¹を持っている場合でも、同じハッシュ値を持つ2つの値の確率が高いということです。これは本質的に悪名高い誕生日のパラドックスの一例です。したがって、通常は競合に対処する必要があり、O1 最悪の場合のアクセス時間の希望を放棄できます。hO1

しかし、平均的なケースはどうですか?すべてのキーが同じ確率で発生すると仮定します。チェックされたエントリの平均数C S n(成功した検索)または。C U n(検索の失敗)は、使用される競合解決方法によって異なります。[0 ..MCnSCnうん

連鎖

すべての配列エントリには、リンクリスト(の先頭へのポインター)が含まれます。予想されるリストの長さは短い()衝突する可能性が高い場合でも。最後に、我々が得る C S N1+αをnm これは、テーブル内にリストを(部分的または完全に)格納することでわずかに改善できます。

CnS1+α2 そして Cnうん1+α22

線形探査

(それぞれの値を検索する。)挿入するとき、位置確認 時間V H V - 1 ... 0 M - 1 ... H V + 1 をこの順に空の位置まで(RESP 。V)発見されました。利点は、ローカルで二次データ構造なしで作業することです。しかし、平均アクセス数は、のために発散α 1C S N1v

hvhv10m1hv+1
vα1 以下のためにα<0.75、しかし、パフォーマンスがchaining²に匹敵します。
CnS121+11α そして Cnうん121+11α2
α<0.75

ダブルハッシュ

線形探査に似ていますが、検索ステップサイズはと互いに素な2番目のハッシュ関数によって制御されます。正式な導出は与えられていないが、経験的な観察が示唆された C SをN1M

CnS1αln11α そして Cnうん11α

テーブルから要素を削除したりテーブルを拡張したりすると、それぞれの方法で難易度が異なることに注意してください。

O1αh


h
Hashtable


10

S{012n}O1O1lSlバツバツSO|l|SO|S|O|l|+|S|O|l||S|Oログ|l||S|O|l|l

O|l|

lうんNSうんバツSllhうん{trあなたはefalse}hhバツ=falseバツうんylhy=trあなたはeO|l|O|うん|

lO|うん|O|1|O|うん|

うんh


O|l|O|S|O|l||S|

hhうん{falsetrあなたはe}h

@Gilles基本的には、リストメンバーシップのルックアップテーブルとして使用されているだけです。モノ自体を保存する代わりに、既知の安価な逆関数を使用した完全なハッシュ関数がある場合、1ビットのみを保存する必要があります(一意のハッシュを持つものが追加されたかどうか)衝突が発生する可能性がある場合、これを行うことはブルームフィルターと呼ばれますが、いずれにしても、メンバーシップの質問に明確な「いいえ」を提供できます。
Patrick87

9

O1

O1O1O1O1


完全なハッシュ関数は完璧ですが、どのように取得できますか?費用はいくらですか?そして、衝突の最大数または予想数を知るにはどうすればよいですか?
ジル

2
@Gillesの完全なハッシュ関数は、可能なすべての入力に対して一意のハッシュを生成する関数です。可能な入力が有限(かつ一意)であれば、これは簡単です。
レイフケトラー

1
@RafeKettler入力は通常、文字列または複合データ構造であり、通常、データが進化するにつれてエントリを追加および削除します。これに対して完璧なハッシュを作成するにはどうすればよいですか?
ジル

4
はい、しかしそれがポイントです。ドメインが範囲より大きい場合、決定論的完全ハッシュ関数は存在しません。
スレシュ

@Suresh:衝突が発生するたびに新しいハッシュ関数を選択し、テーブルのサイズを大きくすることが許可されている場合、テーブル内の既存のデータと新しい1つの挿入しようとしているアイテム-衝突はありません(「完璧」です)。動的完全ハッシュが定期的にランダムな新しいハッシュ関数を選択するのはこのためです。
デビッドケーリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.