Хеширование кукушки — различия между версиями
(→Источники) |
Watson (обсуждение | вклад) (→Зацикливание) |
||
Строка 30: | Строка 30: | ||
==Зацикливание== | ==Зацикливание== | ||
− | Зацикливание может возникнуть при добавлении элемента. Пусть мы добавляем элемент <tex>x</tex>. И обе ячейки <tex>h_1(x)</tex> и <tex>h_2(x)</tex> заняты. Пусть, для определенности, элемент <tex>x</tex> положили в ячейку <tex> | + | Зацикливание может возникнуть при добавлении элемента. Пусть мы добавляем элемент <tex>x</tex>. И обе ячейки <tex>h_1(x)</tex> и <tex>h_2(x)</tex> заняты. Пусть, для определенности, элемент <tex>x</tex> положили в ячейку <tex>h_i(x)</tex>. Если в ходе перемещений элементов в таблице на очередном шаге мы опять хотим переместить элемент <tex>x</tex> в ячейку <tex>h_i(x)</tex>(а это значит что элемент x был перемещен в <tex>h_j(x)</tex> (i \ne j) и затем в ячейку <tex>h_j(x)</tex> что-то перемещается) то значит произошло зацикливание. |
Например зацикливание возникнет если добавить в хэш-таблицу 3 элемента <tex>x,y,z</tex> у которых <tex>h_1(x)</tex> = <tex>h_1(y)</tex> =<tex>h_1(z)</tex> и <tex>h_2(x)</tex> = <tex>h_2(y)</tex> = <tex>h_2(z)</tex> равны. | Например зацикливание возникнет если добавить в хэш-таблицу 3 элемента <tex>x,y,z</tex> у которых <tex>h_1(x)</tex> = <tex>h_1(y)</tex> =<tex>h_1(z)</tex> и <tex>h_2(x)</tex> = <tex>h_2(y)</tex> = <tex>h_2(z)</tex> равны. |
Версия 21:48, 24 апреля 2012
Хеширование кукушки — один из способов борьбы с коллизиями при создании хеш-таблицы.
Алгоритм
Основная идея хеширования кукушки — использование двух хеш-функций вместо одной (далее
и . Так же есть вариант алгоритма, в котором используются две хеш-таблицы, и первая хеш-функция указывает на ячейку из первой таблицы, а вторая — из второй. Рассмотрим алгоритмы функций add(x), delete(x) и exists(x).Add — добавляет элемент с ключом
в хэш-таблицу- Если одна из ячеек с индексами или свободна, кладем в нее элемент. Переходим к шагу 7.
- Иначе произвольно выбираем одну из этих ячеек, запоминаем элемент, который там находится, помещаем туда новый.
- Смотрим в ячейку, на которую указывает другая хеш-функция от элемента, который запомнили, если она свободна, помещаем его в нее. Переходим к шагу 7.
- Иначе запоминаем элемент из этой ячейки, кладем туда старый. Проверяем, не зациклились ли мы.
- Если не зациклились, переходим к шагу 3.
- Иначе выбираем 2 новые хеш-функции(из универсального семейства хэш-функций) и перехешируем все добавленные элементы.
- Помечаем ячейку, в которую только что добавили элемент, как занятую.
- Если хэш-таблица заполнена увеличиваем её размер.
Delete — удаляет элемент с ключом
из хэш-таблицы.- Смотрим ячейки с индексами и .
- Если в одной из них есть искомый элемент, просто помечаем эту ячейку как свободную.
Exists — проверяет на наличие элемента
в хэш-таблице- Смотрим ячейки с индексами и .
- Если в одной из них есть искомый элемент, возвращаем true.
- Иначе возвращаем false.
Зацикливание
Зацикливание может возникнуть при добавлении элемента. Пусть мы добавляем элемент
. И обе ячейки и заняты. Пусть, для определенности, элемент положили в ячейку . Если в ходе перемещений элементов в таблице на очередном шаге мы опять хотим переместить элемент в ячейку (а это значит что элемент x был перемещен в (i \ne j) и затем в ячейку что-то перемещается) то значит произошло зацикливание.Например зацикливание возникнет если добавить в хэш-таблицу 3 элемента
у которых = = и = = равны.Время работы алгоритма
Удаление и проверка происходят за
(что является основной особенностью данного типа хеширования), добавление в среднем происходит за . Первые два утверждения очевидны: требуется проверить всего лишь 2 ячейки таблицы.Утверждение: |
Добавление в среднем происходит за . |
Один из способов доказательства данного утверждения использует теорию случайных графов. Это делается через неориентированный "кукушкин граф", где каждой ячейке хеш-таблицы соответствует ровно одна вершина, а каждому добавленному элементу — ребро с концами в вершинах, соответствующих ячейкам, в которые указывают хеш-функции элемента. При этом элемент будет добавлен без перехеширования тогда и только тогда, когда после добавления нового ребра граф будет оставаться псевдолесом, то есть каждая его компонента связности будет содержать не более одного цикла. |
Таким образом хеширование кукушки является одним из самых быстрых способов хеширования.