Перехеширование — различия между версиями
(→Источники) |
(→При открытом хешировании) |
||
Строка 4: | Строка 4: | ||
При использовании [[Открытое и закрытое хеширование#Открытое хеширование|открытого хеширования]] , элементы с одинаковым результатом хеш-функции помещают в список. Так как операции <tex>Add(x)</tex>, <tex>Exists(x)</tex> и <tex>Delete(x)</tex> работают за <tex>O(l)</tex>, где <tex>l</tex> - длина списка, то с некоторого момента выгодно увеличить размер хеш-таблицы, чтобы поддерживать амортизационную стоимость операции <tex>O(1)</tex>. | При использовании [[Открытое и закрытое хеширование#Открытое хеширование|открытого хеширования]] , элементы с одинаковым результатом хеш-функции помещают в список. Так как операции <tex>Add(x)</tex>, <tex>Exists(x)</tex> и <tex>Delete(x)</tex> работают за <tex>O(l)</tex>, где <tex>l</tex> - длина списка, то с некоторого момента выгодно увеличить размер хеш-таблицы, чтобы поддерживать амортизационную стоимость операции <tex>O(1)</tex>. | ||
− | Рассмотрим следующий алгоритм перехеширования: когда в хеш-таблицу добавлено <tex>\frac{ | + | Рассмотрим следующий алгоритм перехеширования: когда в хеш-таблицу добавлено <tex>\frac{4n}{3}</tex> элементов, где <tex>n</tex> - размер хеш-таблицы, создадим новую хеш-таблицу размера <tex>2n</tex>, и последовательно переместим в нее все элементы первой таблицы. При этом, сменим хеш-функцию так, чтобы она выдавала значения <tex>[0..2n-1]</tex> (в функциях, использующих остаток от деления на длину таблицы, достаточно брать остаток от деления на <tex>2n</tex> вместо остатка от деления на <tex>n</tex>). |
− | Найдем амортизационную стоимость добавления, после которого было сделано перехеширование, используя метод предоплаты. С момента последнего перехеширования было произведено не менее <tex>\frac{ | + | Найдем амортизационную стоимость добавления, после которого было сделано перехеширование, используя метод предоплаты. С момента последнего перехеширования было произведено не менее <tex>\frac{2n}{3}</tex> операций <tex>Add(x)</tex>, так как изначально в массиве находится <tex>\frac{2n}{3}</tex> элементов (или <tex>0</tex> в начале работы), а перехеширование происходит при наличии <tex>\frac{4n}{3}n</tex> элементов. |
− | Для проведения перехеширования необходимо произвести <tex>\frac{ | + | Для проведения перехеширования необходимо произвести <tex>\frac{4n}{3}</tex> операций <tex>Add(x)</tex>, средняя стоимость которых составляет <tex>O(1)</tex> ''(Анализ открытого хеширования, см. Т.Корман, второе издание, стр. 288)'', потратить <tex>\frac{4n}{3}</tex> операций на проход хеш-таблицы, и <tex>\frac{4n}{3}</tex> операций на удаление предыдущей таблицы. В итоге, если мы увеличим стоимость каждой операции <tex>Add(x)</tex> на <tex>6</tex>, то есть на <tex>O(1)</tex>, операция перехеширования будет полностью предоплачена. Значит, амортизационная стоимость перехеширования при открытом типе хеш-таблицы равна <tex>O(1)</tex>. |
===При закрытом типе=== | ===При закрытом типе=== |
Версия 17:10, 5 мая 2012
При добавлении в хеш-таблицу большого количества элементов могут возникнуть ухудшения в ее работе. Обработка любого вызова будет занимать больше времени из-за увеличения размеров цепочек при открытом хешировании или кластеризации при закрытом, также, при закрытом хешировании может произойти переполнение таблицы. Для избежания таких ситуаций используется выбор новой хеш-функции и (или) хеш-таблица большего размера. Этот процесс называется перехеширование.
Содержание
Перехеширование при разных типах хеширования
При открытом хешировании
При использовании открытого хеширования , элементы с одинаковым результатом хеш-функции помещают в список. Так как операции , и работают за , где - длина списка, то с некоторого момента выгодно увеличить размер хеш-таблицы, чтобы поддерживать амортизационную стоимость операции .
Рассмотрим следующий алгоритм перехеширования: когда в хеш-таблицу добавлено
элементов, где - размер хеш-таблицы, создадим новую хеш-таблицу размера , и последовательно переместим в нее все элементы первой таблицы. При этом, сменим хеш-функцию так, чтобы она выдавала значения (в функциях, использующих остаток от деления на длину таблицы, достаточно брать остаток от деления на вместо остатка от деления на ).Найдем амортизационную стоимость добавления, после которого было сделано перехеширование, используя метод предоплаты. С момента последнего перехеширования было произведено не менее
операций , так как изначально в массиве находится элементов (или в начале работы), а перехеширование происходит при наличии элементов.Для проведения перехеширования необходимо произвести
операций , средняя стоимость которых составляет (Анализ открытого хеширования, см. Т.Корман, второе издание, стр. 288), потратить операций на проход хеш-таблицы, и операций на удаление предыдущей таблицы. В итоге, если мы увеличим стоимость каждой операции на , то есть на , операция перехеширования будет полностью предоплачена. Значит, амортизационная стоимость перехеширования при открытом типе хеш-таблицы равна .При закрытом типе
При использовании хеширования с открытой адресацией, или закрытого хеширования , операции , и в худшем случае работают за , где - количество уже добавленных в таблицу элементов, поэтому перехеширование надо проводить при неполном заполнении хеш-таблицы.
Будем проводить перехеширование при заполнении таблицы на
, увеличивая размер таблицы в раза. Аналогично случаю с открытым хешированием, для перехеширования необходимо будет потратить операций на обход таблицы, элементарных операций на добавление элементов, где - стоимость операции , и операций на удаление таблицы. Так как , и между последовательными перехешированиями производится добавлений, то можно предоплатить перехеширование, увеличив стоимость операции на , и не изменив стоимость остальных операций.См. также
Источники
- Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд Алгоритмы: построение и анализ, 2-е издание. Пер. с англ. — М.:Издательский дом "Вильямс", 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)