ハッシュ表(衝突対応)とは?キーから置き場所を計算して一発で出し入れする高速なしくみ

公開: 更新: カテゴリ: テクノロジ系

30秒で結論

ハッシュ表とは(全体像)

ハッシュ表は、「キー(名前)」と「値」をペアで持ち、キーから一発で値を取り出せるしくみ。プログラミング言語の「辞書(dict)」「連想配列」の正体だ。

カギになるのがハッシュ関数。キーを入れると「何番の棚に置くか」を計算してくれる。だから、先頭から順に探さなくても、計算した番号の棚を直接見るだけで済む——これが速さの理由(平均O(1))だ。

ただし、ここで避けられない問題が起きる。

棚の数よりキーの種類のほうが多いので、衝突は必ず起きる(理屈のうえで避けられない)。だから「衝突をどう処理するか」がハッシュ表の肝になる。


詳しく:衝突対応2方式と平均O(1)だけ覚えれば戦える

ここが記事の心臓部。まずは衝突への対応2方式

衝突対応の2方式

方式やり方
チェイン法同じ場所に、リストで数珠つなぎにぶら下げる
オープンアドレス法別の空いている場所を、決めた規則で探す

チェイン法は、同じ棚に複数のキーが来たら、そこにリストでつなげてしまう方法。オープンアドレス法は、ぶつかったら別の空き棚を探して置く方法(探し方には「1つ隣」「飛び飛び」などのルールがある)。

次に、混み具合を表す負荷率

負荷率と速さ

項目内容
負荷率入っている数 ÷ 棚の数(混み具合)
目安だいたい0.7以下に保つ
超えたら棚を増やして入れ直す(再ハッシュ)

負荷率が高い(混んでいる)ほど衝突が増えて遅くなる。だから0.7くらいを目安に保ち、超えたら棚を増やす(再ハッシュ)。つまり、混みすぎる前に棚を増やしておくのが速さを保つコツ、というわけだね。

そして速さの注意点。ハッシュ表は平均ではO(1)(一発)だが、衝突が集中する最悪の場合はO(n)(先頭から探すのと同じ)まで遅くなりうる。「つねに一発」ではない、と押さえておく。

わかりやすく言い換えると

要するに、ハッシュ表は「名前から棚番号を計算して、直接その棚を見る下駄箱」だ。

ハッシュ関数 … 「田中さんは7番」と名前から棚番号を計算する係

衝突 … 「田中さん」と「鈴木さん」がたまたま同じ7番になること

対応 … 7番に2人ぶんの場所をつなげる(チェイン法)か、空いている別の棚へ回す(オープンアドレス法)

棚番号が一発で分かるから速い。でも同じ番号が重なる(衝突する)ことは避けられないので、その処理を決めておく——というわけだね。


試験のツボ

🔴 一番出る:衝突は必ず起きる・対応2方式

①別のキーが同じ場所を指す衝突は避けられない

②チェイン法(同じ場所にリストでつなぐ)

③オープンアドレス法(別の空き場所を探す)

🔴 次に出る:速さは平均O(1)(最悪O(n))

①ふつうは一発で出し入れできる(平均O(1))

②衝突が集中すると最悪O(n)まで遅くなる

🟡 押さえると安定:負荷率

①負荷率=入っている数÷棚の数(混み具合)

②0.7くらいを目安に保ち、超えたら再ハッシュ


よくある間違い

「ハッシュ表では衝突は起きない」→ ✗  棚よりキーの種類が多いので、衝突は必ず起きる。だから対応方式がある。

「ハッシュ表はどんなときも必ずO(1)で取り出せる」→ ✗  平均はO(1)だが、衝突が集中する最悪の場合はO(n)になる。

「負荷率が高い(混んでいる)ほど速くなる」→ ✗  逆。混むほど衝突が増えて遅くなる。0.7くらいを目安に保つ。


試験での出題パターン

実際の問題でたしかめてみよう。

オリジナル問題1(衝突)

📝 オリジナル問題 1 衝突の必然性

ハッシュ表の衝突に関する次の記述のうち、正しいものはどれか。

  1. ハッシュ関数を工夫すれば、衝突をいっさい起こさないようにできるものである
  2. 衝突はプログラムのバグが原因で起こるので、正しく書けば発生しないものだ
  3. 衝突が起きるとデータが消えるため、ハッシュ表は実用では使われないものだ
  4. 別のキーが同じ場所を指す衝突は避けられず、対応方式を用意して処理を行う
オーエスペン
オーエスペン 解答・解説

解答は 4 だよ。

棚の数よりキーの種類のほうが多いから、衝突は必ず起きる(避けられない)んだ。だからチェイン法やオープンアドレス法といった対応方式を用意しておくよ。

選択肢1は「いっさい起こさない」が誤り。選択肢2は「バグが原因」が誤り。選択肢3は「データが消える・使われない」が誤りだよ。

選択肢判定理由
1衝突は避けられない
2バグではなく必然
3対応方式で処理でき実用的
4衝突は避けられず対応方式で処理

オリジナル問題2(対応方式)

📝 オリジナル問題 2 衝突対応の方式

ハッシュ表の衝突対応に関する次の記述のうち、正しいものはどれか。

  1. チェイン法は衝突した要素を消し、オープンアドレス法は上書きする方式である
  2. チェイン法は同じ場所にリストでつなぎ、オープンアドレス法は空き場所を探す
  3. チェイン法もオープンアドレス法も、衝突した要素をすべて捨てる方式である
  4. チェイン法は別の空き場所を探し、オープンアドレス法はリストでつなぐ方式だ
オーエスペン
オーエスペン 解答・解説

解答は 2 だよ。

チェイン法は同じ場所にリストでつなぎ、オープンアドレス法は別の空き場所を探すんだ。どちらも要素を捨てずにちゃんと保管するよ。

選択肢1・3は「消す・捨てる」が誤り。選択肢4はチェイン法とオープンアドレス法のやり方が逆だよ。

選択肢判定理由
1要素は消さない
2チェイン=つなぐ・オープン=別の場所
3要素を捨てない
42方式のやり方が逆

オリジナル問題3(計算量)

📝 オリジナル問題 3 ハッシュ表の計算量

ハッシュ表の検索の速さに関する次の記述のうち、正しいものはどれか。

  1. ハッシュ表はどんなときも必ずO(1)で、最悪の場合でも遅くならないものである
  2. ハッシュ表は平均でO(n)と遅く、配列の先頭から探すのと変わらないものだ
  3. ハッシュ表は平均でO(1)と速いが、衝突が集中する最悪の場合はO(n)になる
  4. ハッシュ表は負荷率が高い(混んでいる)ほど、検索が速くなる性質を持つ
オーエスペン
オーエスペン 解答・解説

解答は 3 だよ。

ハッシュ表は平均ではO(1)で速いけれど、衝突が集中する最悪の場合はO(n)まで遅くなるんだ。「つねに一発」ではない、ってところがポイントだよ。

選択肢1は「最悪でも遅くならない」が誤り。選択肢2は「平均O(n)」が誤り(平均はO(1))。選択肢4は「混むほど速い」が逆だよ。

選択肢判定理由
1最悪はO(n)になりうる
2平均はO(1)で速い
3平均O(1)・最悪O(n)
4混むほど遅くなる

まとめ

押さえどころ

次に学ぶ


執筆: SikakuQuest編集部

勉強は、クエストになった。

資格の勉強を、冒険に変えるRPG学習アプリ

App Storeで見る