Edit this page | Report an issue |
ハッシュ法では様々な衝突回避方法が考案されている。
以下では、格納データ数を $N$、ハッシュ表のサイズを $M$ とする。
ハッシュテーブルの各番地をリスト構造にし、1つの番地に複数のデータを格納する方法を 連鎖法 という。
衝突が起きた際に、なんらかの方法で別の空いているアドレスを探す方法を 開番地法 という。ただし、要素の削除で削除記号を残す工夫が必要である(設問2の回答 を参照)。
主要な手法に以下の3つがある。
衝突が起きるたびに、番地を1つずつずらしていく方法。
1つ目の $h(x)$ を定義した後、ハッシュ関数の列を
\(h_k(x) = h(x) + k \mod M\)
と定義する。衝突が起きた場合は、$h_k(x)$ を順番に試していく。
ただし、再ハッシュのたびに連続した領域を使うため、データが偏った領域に格納される現象 クラスター(clustering)が発生する場合がある。
衝突が起きるたびに、要素ごとにランダムな大きさ だけずらす1。 \(h_k(x) = h(x) + kg(x) \mod M\)
ハッシュ関数の列を $h_k(x) = h(x)+k \mod m$ とする。
また、挿入・削除・探索を行うデータを $x$ とする。
$h_1(x), h_2(x),\cdots$ を順番に試していき、空いている番地(または後述の del
が格納された番地)が見つかり次第、そこに挿入する。
はじめに $h_1(x), h_2(x),\cdots$ を順番に試していき、$x$ の格納された番地まで移動する。$x$ の格納番地 $h_i(x)$ から $x$ を削除し、代わりに削除の痕跡を表す del
を挿入する。
del
が入っていた場合、$i=i+1$ として Step2からやり直す。開番地法のまとめ を参照
設問1,3:各12点
設問2,4:各13点
(50点満点)
コメントはGithubレポジトリにIssueとして投稿されます。
$g(x)=1$ とすれば、線形走査法になる ↩