ハッシュテーブルの基本
algorithmdata-structuresundergraduatelecture
data/lecture/information/algorithm/data-structures/data-structures-portal.lecture.n.md
1導入
この講義では、辞書 ADT をハッシュテーブルで実装する方法を説明する。衝突を連鎖法で処理する場合について、負荷率と計算量の関係を整理する。
2辞書 ADT
辞書 ADT は、キーの集合を管理し、キーに対応する値を記録する抽象データ型である。検索は、キーが存在すれば対応する値を返し、存在しなければ「未登録」を返す。挿入は、未登録のキーと値を追加し、登録済みのキーには対応値を置換する。削除は、登録済みのキーと対応値を除去し、未登録のキーには状態を変更しない。キーの順序は仕様に含まれない。
3ハッシュ関数とバケット
キーの全体を U、バケット数を m とする。ハッシュ関数 は
h:U\to\{0,1,\ldots,m-1\}
によってキーを配列の添字へ対応させる関数である。バケット は、同一の添字へ対応したキーを格納する領域である。キー k の操作では、まず h(k) に対応するバケットを選択する。
衝突 は、相異なるキー k_1,k_2 に対して h(k_1)=h(k_2) が成立することである。U の要素数が m より大きい場合、鳩の巣原理により衝突は不可避である。
4連鎖法
連鎖法 は、各バケットにキーと値の列を保持し、衝突した要素を同一の列へ格納する方式である。検索では h(k) のバケットだけを走査する。挿入と削除でも、同じバケット内でキーを照合する。連鎖を連結リストで実装する場合、操作時間はバケット内の要素数に依存する。
5負荷率と期待計算量
格納されているキーの個数を n とする。負荷率 は
\alpha=\frac{n}{m}
である。入力となるキー列を固定し、ハッシュ関数族から関数を無作為に選択したとき、各キーが m 個のバケットへ一様かつ独立に対応するという単純一様ハッシュ仮定を置く。期待値はこの無作為選択について取る。この仮定の下では、バケットの期待要素数は \alpha である。したがって、連鎖法による検索・挿入・削除の期待時間は O(1+\alpha) となる。\alpha を定数以下に維持すれば、各操作の期待時間は O(1) である。
これは任意のハッシュ関数に対する決定的な保証ではない。すべてのキーが単一のバケットへ集中する場合、検索・挿入・削除の最悪時間は O(n) となる。
6リサイズ
リサイズ は、負荷率が所定の閾値を超過したときに、より大きいバケット配列を確保し、すべてのキーを再配置する操作である。バケット数が変化するとハッシュ値の範囲も変化するため、既存の要素をそのまま複製するだけでは不十分であり、各キーのバケットを再計算する必要がある。
1 回のリサイズには O(n) 時間を要する。ただし、バケット数を定数倍に拡大する方式では、多数の挿入にリサイズ費用を配分できる。リサイズ後にも単純一様ハッシュ仮定を満たす関数を選択し、\alpha を定数以下に維持し、1 回のハッシュ計算を O(1) とする。このとき、挿入の償却期待時間は O(1) となる。
7適用範囲
- キーの完全一致による検索にはハッシュテーブルが適する。
- キーの大小順、範囲検索、最小値を直接扱う場合には、平衡探索木などの順序を保持するデータ構造が適する。
8まとめ
ハッシュテーブルは、ハッシュ関数でバケットを選択し、連鎖法で衝突を処理する。単純一様ハッシュ仮定と有界な負荷率の下では辞書操作を期待 O(1) 時間で実行できるが、最悪時間は O(n) である。
Hash Table Basics
data/lecture/information/algorithm/data-structures/data-structures-portal.lecture.n.md
1Introduction
This lecture explains how a hash table implements the dictionary ADT. For separate chaining, it relates the load factor to operation complexity.
2Dictionary ADT
The dictionary ADT is an abstract data type that maintains a set of keys and records a value associated with each key. Lookup returns the associated value for a present key and an “absent” result otherwise. Insertion adds an absent key-value pair and replaces the associated value of a present key. Deletion removes a present key and its value and leaves the state unchanged for an absent key. The specification does not require an ordering of the keys.
3Hash Functions and Buckets
Let U be the universe of keys and let m be the number of buckets. A hash function is a function
h:U\to\{0,1,\ldots,m-1\}
that maps a key to an array index. A bucket is the storage region for keys mapped to the same index. An operation on key k first selects the bucket indexed by h(k).
A collision occurs when h(k_1)=h(k_2) for two distinct keys k_1 and k_2. If the cardinality of U exceeds m, the pigeonhole principle makes collisions unavoidable.
4Separate Chaining
Separate chaining stores a sequence of key-value pairs in every bucket and places colliding entries in the same sequence. Lookup scans only the bucket selected by h(k). Insertion and deletion likewise compare keys within that bucket. When each chain is implemented as a linked list, an operation's running time depends on the number of entries in its bucket.
5Load Factor and Expected Complexity
Let n be the number of stored keys. The load factor is
\alpha=\frac{n}{m}.
Fix the input sequence of keys and choose a function randomly from a hash-function family. Assume simple uniform hashing: each key maps independently and uniformly to one of the m buckets. The expectation is over this random choice. Under the assumption, the expected number of entries in a bucket is \alpha. Lookup, insertion, and deletion with separate chaining therefore take expected time O(1+\alpha). If \alpha is kept below a constant, each operation takes expected time O(1).
This conclusion is not a deterministic guarantee for every hash function. If all keys map to one bucket, lookup, insertion, and deletion take O(n) time in the worst case.
6Resizing
Resizing allocates a larger bucket array and redistributes all keys when the load factor exceeds a prescribed threshold. Because changing the bucket count changes the range of hash values, merely copying the existing entries is insufficient: the bucket of every key must be recomputed.
A single resize takes O(n) time. If the bucket count grows by a constant factor, however, its cost can be distributed over many insertions. Assume that after resizing a function satisfying simple uniform hashing is selected, that \alpha remains bounded by a constant, and that one hash computation takes O(1) time. Insertion then takes O(1) amortized expected time.
7Scope of Application
- Hash tables are appropriate for exact-key lookup.
- When an application directly requires sorted keys, range queries, or a minimum key, an order-preserving data structure such as a balanced search tree is more appropriate.
8Summary
A hash table selects a bucket with a hash function and resolves collisions by separate chaining. Under simple uniform hashing and a bounded load factor, dictionary operations take expected O(1) time, whereas their worst-case time is O(n).