Моя текущая реализация хэш-таблицы использует линейное зондирование, и теперь я хочу перейти к квадратичному зондированию (а затем и к цепочкам, а также, возможно, к двойному хешированию). Я прочитал несколько статей, учебных пособий, википедии и т. Д ... Но я до сих пор не знаю точно, что мне делать.
Линейный зонд, в основном, имеет шаг 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, я думаю, что мне нужно изменить метод расчета размера шага "index", но я не понимаю, как мне это делать. Я видел разные фрагменты кода, и все они несколько отличаются.
Кроме того, я видел несколько реализаций Quadratic Probing, в которых хеш-функция изменена, чтобы приспособиться к этому (но не ко всем). Это изменение действительно необходимо, или я могу избежать изменения хеш-функции и все еще использовать Quadratic Probing?
EDIT:
Прочитав все, что указал Эли Бендерский ниже, я думаю, что получил общее представление. Вот часть кода на 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 }
Есть две вещи, которые я не получаю ... Они говорят, что квадратичное зондирование обычно выполняется с использованием 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;
... потому что я видел другие примеры кода, ныряющие вдвое. Хотя я не понимаю, почему ...
1) Почему вычитается шаг?
2) Почему он ныряет на 2?