Моя текущая реализация хеш-таблицы использует линейное зондирование, и теперь я хочу перейти к квадратичному зондированию (а позже к цепочке и, возможно, также к двойному хешированию). Я прочитал несколько статей, руководств, википедии и т. Д. Но я все еще не знаю, что мне делать.
По сути, линейное зондирование имеет шаг 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 */);
Что касается квадратичного зондирования, я думаю, что мне нужно изменить способ вычисления «индексного» шага, но это то, что я не понимаю, как мне это делать. Я видел разные фрагменты кода, и все они несколько разные.
Кроме того, я видел несколько реализаций квадратичного зондирования, в которых хэш-функция была изменена, чтобы приспособить это (но не все из них). Действительно ли это изменение необходимо, или я могу избежать изменения хеш-функции и по-прежнему использовать квадратичное зондирование?
РЕДАКТИРОВАТЬ: Прочитав все, что указано Эли Бендерски ниже, я думаю, что у меня есть общее представление. Вот часть кода по адресу http://eternalconfuzzled.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;
... потому что я видел другие примеры кода, которые ныряли вдвое. Хотя не понимаю почему ...
1) Почему он вычитает шаг?
2) Почему он занижает его на 2?