Этот ответ суммирует части TAoCP Vol 3, гл. 6.4.
Предположим, у нас есть набор значений , из которых мы хотим сохранить в массиве размером . Мы используем хеш-функцию ; как правило,, Мы называем коэффициент нагрузки по . Здесь мы примем натуральное ; в практических сценариях у нас есть , и мы должны отобразить самостоятельно.n A m h : V → [ 0 .. M ) M ≪ | V | α = nVnAmh:V→[0..M)M≪|V| Am=Mm≪Mmα=nmAm=Mm≪Mm
Первое наблюдение состоит в том, что даже если имеет одинаковые характеристики, вероятность того, что два значения имеют одинаковое значение хеш-функции, высока; по сути, это пример печально известного парадокса дня рождения . Поэтому нам обычно приходится иметь дело с конфликтами, и мы можем отказаться от надежды на время доступа в худшем случае.O ( 1 )hO(1)
А как насчет среднего случая, хотя? Предположим, что каждый ключ из встречается с одинаковой вероятностью. Среднее количество проверенных записей (успешный поиск) соотв. (неудачный поиск) зависит от используемого метода разрешения конфликтов.C S n C U n[0..M)CSnCUn
Цепной
Каждая запись массива содержит (указатель на начало) связанных списков. Это хорошая идея, потому что ожидаемая длина списка мала ( ), даже если вероятность возникновения коллизий высока. В конце мы получаем
Это можно немного улучшить, сохранив списки (частично или полностью) внутри таблицы. C S n ≈1+αnm
CSn≈1+α2 and CUn≈1+α22.
Линейное зондирование
При вставке (соответственно поиске значения) проверяйте позиции
в этом порядке до пустой позиции (соотв. ) найдено. Преимущество в том, что мы работаем локально и без вторичных структур данных; тем не менее, число средних обращений расходится для :
Однако для производительность сопоставима с цепочкой².v
h(v),h(v)−1,…,0,m−1,…,h(v)+1
vα→1CSn≈12(1+11−α) and CUn≈12(1+(11−α)2).
α<0.75
Двойное хеширование
Подобно линейным зондированием , но размер шага поиска управляется с помощью второго хеш - функции , которая является взаимно простое с . Формальный вывод не приводится, но эмпирические наблюдения показывают, что
Этот метод был адаптирован Брентом; его вариант амортизирует повышенные затраты на вставку с помощью более дешевых поисков.M
CSn≈1αln(11−α) and CUn≈11−α.
Обратите внимание, что удаление элементов из таблиц и их расширение имеет различную степень сложности для соответствующих методов.
В итоге, вы должны выбрать реализацию, которая хорошо адаптируется к вашим типичным случаям использования. Ожидаемое время доступа в возможно, если не всегда гарантировано. В зависимости от используемого метода поддержание низком уровне имеет важное значение; Вы должны обменять (ожидаемое) время доступа на пространство над головой. Хороший выбор для также центральный, очевидно.O(1)αh
1] Поскольку произвольно тупые неосведомленные программисты могут предоставить , любое предположение относительно его качества является натяжкой на практике.
2] Обратите внимание, что это совпадает с рекомендациями по использованию Java .h
Hashtable