- •16. Хеширование. Постановка задачи, коэффициент заполнения таблицы.
- •18. Идеальная хеш-функция. Примеры хеш-функций (деление с остатком, середина квадрата и т.Д.)
- •19. Методы разрешения коллизий: внешние и внутренние цепочки, линейное и квадратичное опробование, смена системы счисления, применение суперпозиции двух «близких» хеш-функций.)
- •20. Рехеширование. Поведение зависимости числа коллизий от коэффициента заполнения в различных случаях (сравнение).
- •2.3.1. Линейное рехеширование
- •2.3.2. Случайное рехеширование
- •2.3.3. Рехеширование сложением
- •Эффективность операций в хеш - таблице
20. Рехеширование. Поведение зависимости числа коллизий от коэффициента заполнения в различных случаях (сравнение).
Предположим, что мы хешируем символ S и обнаруживаем, что другой символ уже занял элемент с
номером h. Возникает коллизия. Тогда сравниваем S c элементом в ячейке h + p1 (для некоторого целого
p1). Если снова возникает коллизия, сравниваем S с элементом h + p2. Это продолжается до тех пор, пока
не встретится ячейка h + pi, которая либо пуста, либо содержит S, либо совпадает с ячейкой h (pi = 0). В
последнем случае считаем, что таблица переполнена.
Таким образом, если возникло i коллизий, будет выполнено i + 1 сравнение с элементами таблицы.
Элементы pi должны выбираться так, чтобы ожидаемое число сравнений было невелико, но при этом
рассматривалось большее число элементов. В идеальном случае pi должны охватывать целые числа 0, 1,
…, n – 1.
Существуют несколько способов рехеширования. Рассмотрим некоторые из них.
2.3.1. Линейное рехеширование
Это простейший метод рехеширования, состоящий в том, чтобы принять p1 = 1, p2 = 2, p3 = 3 и так
далее. В этом случае мы двигаемся по таблице вперед относительно значения h(a) до тех пор, пока не
исчезнет коллизия. Если достигнута позиция n – 1, переходим на позицию 0. Метод прост для выполне-
ния, однако, если уже возник конфликт, то занятые позиции имеют тенденцию скапливаться. Метод вы-
ражается формулой
hi (a) = (h(a) + i) mod n, 1 ≤ i ≤ n −1
2.3.2. Случайное рехеширование
Этот метод снимает проблему скопления, которая свойственна линейному рехешированию, за счет
выбора в качестве pi достаточно использовать самый элементарный генератор случайных чисел, вы-
дающий все числа в интервале от 0 до n – 1 по одному разу. Каждый раз, когда используется генератор
случайных чисел, он устанавливается в одно и то же состояние. Таким образом, когда происходит об-
ращение к h, генерируется одна и та же последовательность p1, p2, … .
2.3.3. Рехеширование сложением
В этом случае принимаем pi = i * h, где h – исходный хеш-индекс. Таким образом рассматриваются
элементы таблицы с номерами h, 2h, 3h, 4h … . Этот метод хорош, если размерность таблицы n будет
простым числом, то все последовательности полностью покроют все возможные индексы 1, …, n – 1.
Метод описывается формулой:
hi (a) = (ih(a)) mod n, 1 ≤ i ≤ n −1
Эффективность операций в хеш - таблице
Алгоритмы чтения или модификации, вставки и удаления элементов зависят от структуры хеш-таблицы. Если используется хеш-таблица с цепочками коллизий, то алгоритмы поиска, вставки и удаления элемента действуют по однотипной схеме:
· хеширование ключа элемента и вычисление индекса заголовка списка в массиве цепочек коллизий,
· поиск в списке элемента с заданным ключом,
· выполнение операции над элементом.
Трудоёмкость операций зависит от средней длины списков, которую можно вычислить как α = n/m, где n – число занесенных в таблицу элементов, m – размер хеш-таблицы. С учётом первоначального хеширования ключа перед просмотром списка оценку трудоёмкости можно записать, как O(1+α/2) [2]. Величина α учитывает фактор заполнения таблицы и называется коэффициентом заполнения таблицы. Трудоёмкость операций в хеш-таблице зависит не от числа элементов n, содержащихся в ней, а от коэффициента заполнения α. Для хеш-таблиц с цепочками коллизий величина α может быть меньше и больше единицы.
Зависимость трудоёмкости операций от заполнения справедлива и для хеш-таблиц с открытой адресацией. Чем более заполнена хеш-таблица, тем больше возникает коллизий и проб при зондировании. Приведённые в приложении 5 алгоритмы трёх основных операций для хеш-таблицы с открытой адресацией демонстрируют этот процесс.
Так же, как при анализе хеширования с цепочками коллизий, трудоёмкость операций с открытой адресацией оценивается в терминах коэффициента заполнения α. Для открытой адресации α ≤ 1. Анализ трудоёмкости операций для хеш-таблиц с открытой адресацией более сложен, чем для хеш-таблиц с цепочками коллизий. Помимо коэффициента α трудоёмкость операции зависит от её алгоритма, метода зондирования, вероятности промахов операций. Поскольку в основе всех операций лежит определение наличия или отсутствия ключа в таблице, то трудоёмкость операций оценивается в количестве проб зондирования, выполненных при поиске ключа. Ниже приведены оценки трудоёмкости успешного или не успешного поиска ключа в зависимости от метода зондирования [6]:
Метод зондирования |
Успешный поиск ключа |
Не успешный поиск ключа |
Линейное зондирование |
1/2 |
(1/2 (1+ 1/(1- α))2 |
Квадратичное зондирование |
-ln(1- α)/ α |
1/(1- α) |
Зондирование с двойным хешированием |
-ln(1- α)/ α |
1/(1- α) |
Обход хеш-таблицы заключается в просмотре всех элементов, хранящихся в хеш-таблице для выполнения над ними некоторой операции. Для хеш-таблиц с цепочками коллизий обход сводится к просмотру всех непустых списков. Поэтому трудоёмкость обхода можно оценить, как сумму длин просмотренных списков, которая равна числу элементов в таблице. То есть, трудоёмкость обхода имеет оценку O(n). В хеш-таблице с открытой адресацией ведётся поиск всех занятых ячеек, хранящих данные. Трудоёмкость просмотра соответствует размеру хеш-таблицы и выражается оценкой O(m).
