Хеш-таблицы (открытый ключ)

Материал из Algocode wiki
Версия от 15:34, 24 января 2020; Rationalex (обсуждение | вклад) (Новая страница: «Аналогично с хеш-таблицей с помощью цепочек, хеш-таблица с открыт...»)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Аналогично с хеш-таблицей с помощью цепочек, хеш-таблица с открытым ключом пытается сохранять все ключи, которые в неё добавляются, в некоторую структуру данных, однако в отличие от своего брата-близнеца, делает это немного по-другому и гораздо оптимальнее по памяти.

Структура

Заведём вектор длины $M$, где $M ~- $ максимальное значение хеш-функции $h$. По аналогии с хешированием цепочками, сначала это будет небольшая константа, а по мере заполнения хеш-таблицы мы будем её увеличивать. Далее в тексте по хеш-функцией $h$ автор имеет в виду остаток от хеш-функции по модулю $M$.

Добавление

При добавлении ключа $k$ в хеш-таблицу, мы сначала считаем его хеш, берём его по модулю $M$, и затем кладём в ячейку с получившимся номером $h(k)$. Если она занята (например, до этого добавили другой ключ с таким же значением хеш-функции), то пытаемся положить в $h(k)+1$, $h(k)+2$ итд до тех пор, пока не найдём свободную ячейку (или ячейку, из которой что-то удалили, но об этом чуть позже).

Проверка на наличие

Пусть мы хотим проверить, лежит ли ключ $k$ в нашей хеш-таблице. Посчитаем $h(k)$ и посмотрим на ячейку с таким номером. Если она свободна, значит такого ключа нет в таблице (поймите почему!). Если же ячейка занята, но там лежит не тот ключ, который мы ищем, пойдём в $h(k) + 1$ и так до тех пор, пока мы либо не найдём свободную ячейку, либо не найдём наш ключ, либо не обойдём всю хеш-таблицу, не найдя ни первого ни второго. Если мы нашли свободную ячейку, то ключа нет, если мы нашли ключ, то он есть ( =) ), а если мы обошли всю хеш-таблицу и ничего не нашли, то ключа тоже нет. Более того, если мы обошли всю хеш-таблицу и все ячейки заняты, то надо провести перехеширование, о чём можно прочитать ниже.

Удаление

Чтобы удалить ключ, его сначала надо найти, для этого см. предыдущий пункт. Затем, если его просто удалить из ячейки, то дальнейшие поиски, которые должны были бы пройти мимо этой ячейки, наткнутся на пустую ячейку и решат, что ключа, который они ищут нет, что может быть неверно. Поэтому вместо удаления мы будем класть в такие ячейки специальное значение DELETED, которое не встречается среди ключей.

Перехеширование

Аналогично с хешированием цепочками, будем перехешировать нашу хеш-таблицу когда load_factor становится больше $\frac{3}{4}$. Для этого заведём хеш-таблицу с вдвое большим числом бакетов и все старые ключи закинем в неё (с новой хеш-функцией), а старую хеш-таблицу удалим.