オープンアドレスハッシュ法について解説します。 ハッシュについての基本的な記述については、こちらに載せてあります。
オープンアドレスハッシュ法は、ハッシュで問題となっていた、 計算したキーのハッシュ値が同じになる要素については、格納できないという問題を、 ハッシュ値が衝突してしまった場合、再び計算してハッシュ値を求めなおすことで問題を解決します。
まず例として、ハッシュで格納したハッシュの状態を見てください。
key value
+--------+-------------+
(0) | Albert | 855-69-7889 |
+--------+-------------+
(1) | empty | empty |
+--------+-------------+
(2) | Ciel | 854-37-4645 |
+--------+-------------+
(3) | empty | empty |
+--------+-------------+
(4) | Edy | 450-69-8887 |
+--------+-------------+
(5) | empty | empty |
+--------+-------------+
(6) | empty | empty |
+--------+-------------+
ハッシュでは、ハッシュ値が0番になる要素と、ハッシュ値が2番になる要素、
それにハッシュ値が4番になる要素は、
もうこのハッシュに格納することができないという問題がありました。
オープンアドレス法の場合は、例えばEricをハッシュに追加したいと考えたときに、 先ほど決めたハッシュ関数を使ってハッシュ値を求めると、 Edyの位置と重なってしまいますが、 この時、もう一度ハッシュ値を求めなおします。 このことをリハッシュといい、 リハッシュのためのルールをリハッシュ関数といいます。 例えばここでは、リハッシュ関数を、「ハッシュ関数+1」とします。 すると、Ericを追加したいと思ったときのプロセスは、次のようになります。
key value
+--------+-------------+
(0) | Albert | 855-69-7889 |
+--------+-------------+
(1) | empty | empty |
+--------+-------------+
(2) | Ciel | 854-37-4645 |
+--------+-------------+
(3) | empty | empty |
+--------+-------------+
(4) | Edy | 450-69-8887 |
+--------+-------------+
(5) | Eric | 786-88-1272 |
+--------+-------------+
(6) | empty | empty |
+--------+-------------+
このようにオープンアドレスハッシュ法は、何も格納されていないハッシュ値が計算されるまで、
リハッシュの計算を続けることになります。
もしもEricの電話番号を知りたいと思ったときには、
ここで、Edyの要素を削除したとします。
key value
+--------+-------------+
(0) | Albert | 855-69-7889 |
+--------+-------------+
(1) | empty | empty |
+--------+-------------+
(2) | Ciel | 854-37-4645 |
+--------+-------------+
(3) | empty | empty |
+--------+-------------+
(4) | empty | empty |
+--------+-------------+
(5) | Eric | 786-88-1272 |
+--------+-------------+
(6) | empty | empty |
+--------+-------------+
そしてEricについて検索したいと思います。
Ericからハッシュ関数でハッシュ値を求めると、4となるのですが、4番目はempty(空)となっています。
これではつまり、Ericのデータがハッシュに入っていないということになってしまいます。
この問題が起きないためにも、オープンアドレスハッシュ法の要素を削除したいときには、 削除したい要素位置に、「削除されました」というフラグを付けます。 すると、こうなります。
key value
+--------+-------------+
(0) | Albert | 855-69-7889 |
+--------+-------------+
(1) | empty | empty |
+--------+-------------+
(2) | Ciel | 854-37-4645 |
+--------+-------------+
(3) | empty | empty |
+--------+-------------+
(4) | delete | delete |
+--------+-------------+
(5) | Eric | 786-88-1272 |
+--------+-------------+
(6) | empty | empty |
+--------+-------------+
この状態ならば、Ericについて調べることができます。
オープンアドレスハッシュ法の問題点は、リハッシュの計算回数が多くなると、 その計算に処理時間をとられる点と、 チェインハッシュ法とは異なり、ハッシュに格納できる要素の数が有限であるという点です。