TGViewer
Чайник из Юты Чайник из Юты @irrationalthings · 121 subscribers
Post #524 253
Способы разрешения коллизий

В продолжение темы о хэшмапах, как структура данных таковые полагаются полностью на хэшфункцию - что логично. Но поскольку коллизии в общем случае неизбежны (исключения - идеальные хэш- и identity-функции), то их разрешать как-то всё равно да и приходится. И основополагающих принципа существует всего два:

1) Закрытая адресация (она же separate chaining) - способ был впервые описан во внутреннем меморандуме в IBM в 1953 году. Это как раз классическая схема, которая была использована и в старой гошной мапе. Базовый случай - хэшфункцией мы адресуем связной список из вхождений (вхождение есть пара ключ-значение), где уже линейно искомое значение и ищем. Гошная мапа просто немного уменьшила футпринт за счёт связного списка бакетов, где бакет держит сразу до 8 вхождений, и сравнения по верхушке хэша, что даёт хороший бонус для значений, у которых операция сравнения является довольно дорогой (те же строки).

2) Открытая адресация - появилась чуть позже, пускай и с разницей всего в пару лет (что неудивительно - основой послужил как раз-таки тот самый меморандум с закрытой адресацией). В ней больше не используется концепция двухмерного массива, и заместо все значения лежат в одном большом массиве (где вхождения называют слотами). Само разрешение коллизий тогда работает достаточно просто - всё так же адресуем слот в массиве по хэшу, и если он нам не подходит (для вставки - уже оккупирован, для лукапа - не совпадает ключ), тогда мы просто идём дальше и смотрим следующий слот. Правда, как именно мы выбираем следующий слот - тоже тема для отдельного разговора: есть linear probing, когда мы сдвигаем индекс слота на константу (обычно 1), есть quadratic probing, когда мы, соответственно, сдвигаем индекс уже на результат какого-нибудь квадратического уравнения. Есть совсем уж страшное double hashing, когда сдвиг разрешается второй хэш-функцией. Суть методов quadratic probing и double hashing заключается исключительно в том, чтобы снизить так званую кластеризацию - неравномерное распределение элементов, когда они скапливаются на каком-то одном промежутке (double hashing даёт наилучший результат, но по производительности самый худший, а вот quadratic probing есть золотая середина с достаточно тонко подобранными значениями). Плоха кластеризация тем, что без перебора слотов в общем случае не обойтись, а это линейная сложность - всё-таки хотелсь бы амортизированную константу, пускай качество самой хэш-функции и отыгрывает здесь гораздо большую роль - но мир, увы, не идеален.


Конечно, помимо вышеперечисленных двух способов, существуют и другие разновидности (Coalesced hashing, Cuckoo hashing, Hopscotch hashing, Robin Hood hashing), но все они, так или иначе, основываются на открытой адресации.


Фанфакт: "открытая адресация" открытая потому, что все элементы вот у нас в одном массивчике как надо лежат, и мы по ним по всем проходимся, когда как при закрытой адресации все слоты находятся в отдельной структуре данных, виртуально не имеющего ничего общего с массивом этих самых слотов. То есть, при открытой адресации мы адресуем слот со значением, а при закрытой - коробочку, по которой дальше уже как-то сам ходи ищи-свищи.
  • 👍 4
  • ❤ 1
More from @irrationalthings
  1. Sep 21, 2026я хрюкнул
  2. Sep 21, 2026гемини
  3. Sep 15, 2026Тот факт, что между нейронками и компрессорами больше общего, чем может показаться - забав…
  4. Sep 15, 2026"Low-Resource" Text Classification: A Parameter-Free Classification Method with Compressor…
  5. Sep 15, 2026Конечно, они сравнивали со средненькими классифицирующими моделями. Там есть пространство…
  6. Sep 15, 2026GZIP наносит ответный удар Вот мы хотим классифицировать текст. Классическая задача для ML…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →