Изменения

Перейти к: навигация, поиск

Разрешение коллизий

990 байт добавлено, 23:30, 3 января 2019
Линейное разрешение коллизий
'''Разрешение [[Хеш-таблица|коллизий]]''' (англ. collision resolution) в [[Хеш-таблица|хеш-таблице]], задача, решаемая несколькими способами: метод цепочек, открытая адресация и т. Напримерд. Очень важно сводить количество коллизий к минимуму, при помощи метода цепочке или открытой адресации. Коллизии замедляют так как это увеличивает время работы с хеш-таблицой, поэтому с ними нужно боротьсятаблицами.
== Разрешение коллизий с помощью цепочек ==
Каждая ячейка <tex>i</tex> массива <tex>H</tex> содержит указатель на начало [[Список|списка]] всех элементов, хеш-код которых равен <tex>i</tex>, либо указывает на их отсутствие. Коллизии приводят к тому, что появляются списки размером больше одного элемента.
ВремяВ зависимости от того нужна ли нам уникальность значений операции вставки у нас будет работать за разное время. Если не важна, то мы используем список, необходимое для время вставки в наихудшем который будет в худшем случае равно равна <tex>O(1)</tex>. Это операция выполняет быстро, так как считаетсяИначе мы проверяем есть ли в списке данный элемент, что вставляемый элемент отсутствует а потом в таблице, но если потребуется, то перед вставкой случае его отсутствия мы можем выполнить поиск этого его добавляем. В таком случае вставка элемента.в худшем случае будет выполнена за <tex>O(n)</tex>
Время работы поиска в наихудшем случае пропорционально длине списка, а если все <tex>n</tex> ключей захешировались в одну и ту же ячейку (создав список длиной <tex>n</tex>) время поиска будет равно <tex>\Theta(n)</tex> плюс время вычисления хеш-функции, что ничуть не лучше, чем использование связного списка для хранения всех <tex>n</tex> элементов.
== Линейное разрешение коллизий ==
[[Файл:close_hash.png|thumb|380px|right|Пример хеш-таблицы с открытой адресацией и линейным пробированием.]]
Все элементы хранятся непосредственно в хеш-таблице, без использования связных списков. В отличии отличие от хеширования с цепочками, при использовании этого метода может возникнуть ситуация, когда хеш-таблица окажется полностью заполненной, следовательно , будет невозможно добавлять в неё новые элементы. Так что при возникновении такой ситуации решением может быть динамическое увеличение размера хеш-таблицы, с одновременной её перестройкой.
=== Стратегии поиска ===
''' Псевдокод '''
'''function''' delete('''Item''' i) :
j = i + q
'''while''' table[j] == '''null''' '''or''' table[j].key != table[i].key '''if''' table[j] == '''null''' table[i] = '''null'''
'''return'''
j += q
table[i] = table[j]
delete(j);
Хеш-таблицу считаем зацикленной
'''Вставка'''
'''function''' add('''Item''' item):
x = h1(item.key)
y = h2(item.key)
'''for''' (i = 0..m)
'''if''' table[x] == '''null'''
table[x] = item
'''return'''
'''Поиск'''
'''Item''' search('''Item''' key):
x = h1(key)
y = h2(key)
'''for''' (i = 0..m)
'''if''' table[x] != '''null'''
'''if''' table[x].key == key
'''return''' table[x]
'''else'''
'''return''' '''null'''
x = (x + y) '''mod''' m
'''return''' '''null'''
===Реализация с удалением===
Что бы Чтобы наша хеш-таблица поддерживала удаление, требуется добавить массив <tex>deleted</tex> типов <tex>bool</tex>, равный по величине массиву <tex>table</tex>. Теперь при удалении мы просто будем помечать наш объект ''как удалённый'', а при добавлении как ''не удалённый'' и замещать новым добавляемым объектом. При поиске, помимо равенства ключей, мы смотрим, удалён ли элемент, если да, то идём дальше.
'''Вставка'''
'''function''' add('''Item''' item):
x = h1(item.key)
y = h2(item.key)
deleted[x] = '''false'''
'''return'''
x = (x + i * y) '''mod''' m
table.resize()<span style="color:Green">// ошибка, требуется увеличить размер таблицы
'''Поиск'''
'''Item''' search('''Item''' key):
x = h1(key)
y = h2(key)
'''Удаление'''
'''function''' remove('''Item''' key):
x = h1(key)
y = h2(key)
x = (x + y) '''mod''' m
== Разрешение коллизий в Java 8Альтернативная реализация метода цепочек==В Java 8 для разрешения коллизий используется модифицированный метод цепочек. Суть его заключается в том, что когда количество элементов в корзине превышает определенное значение, данный бакет данная корзина переходит от использования связного списка к использованию [[АВЛ-дерево|сбалансированного дерева]]. Но данный метод имеет смысл лишь тогда, когда на элементах хеш-таблицы задан [[Отношение порядка|линейный порядок]]. То есть при использовании данный типа <tex>\mathbf{int}</tex> или <tex>\mathbf{double}</tex> имеет смысл переходить к дереву поиска, а при использовании каких-нибудь ссылок на объекты не имеет, так как они не реализуют нужный интерфейс. Такой подход позволяет улучшить производительность с <tex>O(n)</tex> до <tex>O(\log(n))</tex>. Данный способ используется в таких коллекциях как HashMap, LinkedHashMap и ConcurrentHashMap. [[Файл:Hashing_in_Java8.png|400px500px|Хеширование в Java 8.]]
==См. также==
* [[Идеальное_хеширование|Идеальное хеширование]]
== Источники Информации информации ==
* Бакнелл Дж. М. «Фундаментальные алгоритмы и структуры данных в Delphi», 2003
* Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд «Алгоритмы: построение и анализ», 2-е издание. Пер. с англ. — М.:Издательский дом "Вильямс", 2010.— Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)
[[Категория: Дискретная математика и алгоритмы]]
[[Категория: Хеширование]]
[[Категория: Структуры данных]]
1
правка

Навигация