ハッシュテーブルの現在の実装は線形プロービングを使用しており、今度は2次プロービングに移行したいと思います(後でチェーン化とおそらくダブルハッシュにも移行します)。いくつかの記事、チュートリアル、ウィキペディアなどを読みましたが、まだ正確に何をすべきかわかりません。
線形プロービングは、基本的に1のステップがあり、それは簡単に実行できます。ハッシュテーブルから要素を検索、挿入、または削除するときは、ハッシュを計算する必要があり、そのために次のことを行います。
index = hash_function(key) % table_size;
次に、検索、挿入、または削除中に、次のように空きバケットが見つかるまでテーブルをループします。
do {
if(/* CHECK IF IT'S THE ELEMENT WE WANT */) {
// FOUND ELEMENT
return;
} else {
index = (index + 1) % table_size;
}
while(/* LOOP UNTIL IT'S NECESSARY */);
Quadratic Probingに関しては、「インデックス」ステップサイズの計算方法を変更する必要があると思いますが、それをどのように行うべきかわかりません。私はさまざまなコードを見てきましたが、それらはすべて多少異なります。
また、ハッシュ関数がそれに対応するように変更されたQuadratic Probingのいくつかの実装を見てきました(すべてではありません)。その変更は本当に必要ですか、それともハッシュ関数の変更を避けてQuadratic Probingを使用できますか?
編集: 以下のEli Benderskyによって指摘されたすべてを読んだ後、私は一般的な考えを得たと思います。http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_hashtable.aspxのコードの一部は次のとおりです。
15 for ( step = 1; table->table[h] != EMPTY; step++ ) {
16 if ( compare ( key, table->table[h] ) == 0 )
17 return 1;
18
19 /* Move forward by quadratically, wrap if necessary */
20 h = ( h + ( step * step - step ) / 2 ) % table->size;
21 }
私が得られないことが2つあります...彼らは、二次プロービングは通常、を使用して行われると言いますc(i)=i^2
。ただし、上記のコードでは、次のようなことを行っていますc(i)=(i^2-i)/2
私はこれを自分のコードに実装する準備ができていましたが、単純に次のようにします。
index = (index + (index^index)) % table_size;
...ではなく:
index = (index + (index^index - index)/2) % table_size;
どちらかといえば、私はします:
index = (index + (index^index)/2) % table_size;
...他のコード例が2つに分かれているのを見たからです。理由はわかりませんが...
1)なぜステップを引くのですか?
2)なぜ2でダイビングするのですか?