Хеш-таблица — различия между версиями
Строка 40: | Строка 40: | ||
На поиск элемента в хеш-таблице в худшем случае, может потребоваться столько же времени, как и в списке, а именно <tex>\Theta(n)</tex>, но на практике хеширование более эффективно. При некоторых разумных допущениях математическое ожидание времени поиска элемента в хеш-таблице составляет <tex>O(1)</tex>. А все операции (поиск, вставка и удаление элементов) в среднем выполняются за время <tex>O(1)</tex>. | На поиск элемента в хеш-таблице в худшем случае, может потребоваться столько же времени, как и в списке, а именно <tex>\Theta(n)</tex>, но на практике хеширование более эффективно. При некоторых разумных допущениях математическое ожидание времени поиска элемента в хеш-таблице составляет <tex>O(1)</tex>. А все операции (поиск, вставка и удаление элементов) в среднем выполняются за время <tex>O(1)</tex>. | ||
При этом не гарантируется, что время выполнения отдельной операции мало́, так как при достижении некоторого значения коэффициента заполнения необходимо [[Перехеширование. Амортизационный анализ|перехешировать]] таблицу: увеличить размер массива <tex>H</tex> и заново добавить в новую хеш-таблицу все пары. | При этом не гарантируется, что время выполнения отдельной операции мало́, так как при достижении некоторого значения коэффициента заполнения необходимо [[Перехеширование. Амортизационный анализ|перехешировать]] таблицу: увеличить размер массива <tex>H</tex> и заново добавить в новую хеш-таблицу все пары. | ||
+ | |||
+ | ===Хеширование в современных языках программирования=== | ||
+ | |||
+ | Почти во всех современных языках присутствуют классы, реализующие хеширование. Рассмотрим некоторые из них. | ||
+ | *Java | ||
+ | **HashMap {{---}} реализация интерфейса ассоциативного массива с использованием хеш-таблицы, | ||
+ | **HashSet {{---}} реализация интерфейса множества с использованием хеш-таблицы, | ||
+ | **LinkedHashMap {{---}} потомок класса HashMap. Позволяет просматривать значения в том порядке, в котором они были добавлены. | ||
+ | *C++ | ||
+ | **hash_map {{---}} реализация интерфейса ассоциативного массива с использованием хеш-таблицы, | ||
+ | **hash_set {{---}} реализация интерфейса множества с использованием хеш-таблицы. | ||
== Примечания == | == Примечания == |
Версия 21:06, 4 июня 2015
Определение: |
Хеш-табли́ца (англ. hash-table) — структура данных, реализующая интерфейс ассоциативного массива. В отличие от деревьев поиска, реализующих тот же интерфейс, обеспечивают меньшее время отклика в среднем. Представляет собой эффективную структуру данных для реализации словарей, а именно, она позволяет хранить пары (ключ, значение) и выполнять три операции: операцию добавления новой пары, операцию поиска и операцию удаления пары по ключу. |
Содержание
Введение
Существует два основных вида хеш-таблиц: с цепочками и открытой адресацией. Хеш-таблица содержит некоторый массив
, элементы которого есть пары (хеш-таблица с открытой адресацией) или списки пар (хеш-таблица с цепочками).Выполнение операции в хеш-таблице начинается с вычисления хеш-функции от ключа. Хеш-код
играет роль индекса в массиве , а зная индекс, мы можем выполнить требующуюся операцию (добавление, удаление или поиск).Количество коллизий зависит от хеш-функции; чем лучше используемая хеш-функция, тем меньше вероятность их возникновения. При вставке в хеш-таблицу вероятность коллизии в общем случае превышает 50%[1] (при равномерном распределении значений хеш-функции)[2]. Способ разрешения коллизий — важная составляющая любой хеш-таблицы.
Полностью избежать коллизий для произвольных данных невозможно в принципе, и хорошая хеш-функция в состоянии только минимизировать их количество. Но, в некоторых специальных случаях их удаётся избежать. Если все ключи элементов известны заранее, либо меняются очень редко, то можно подобрать хеш-функцию, с помощью которой, все ключи будут распределены по хеш-таблице без коллизий. Это хеш-таблицы с прямой адресацией; в них все операции, такие как: поиск, вставка и удаление работают за
.Если мы поделим число хранимых элементов на размер массива
(число возможных значений хеш-функции), то узнаем коэффициент заполнения хеш-таблицы (англ. load factor). От этого параметра зависит среднее время выполнения операций.Хеширование
Определение: |
Хеширование — класс методов поиска, идея которого состоит в вычислении хеш-кода, однозначно определяемого элементом с помощью хеш-функции, и использовании его, как основы для поиска (индексирование в памяти по хеш-коду выполняется за методы для борьбы с ними. | ). В общем случае, однозначного соответствия между исходными данными и хеш-кодом нет в силу того, что количество значений хеш-функций меньше, чем вариантов исходных данных, поэтому существуют элементы, имеющие одинаковые хеш-коды — так называемые коллизии, но если два элемента имеют разный хеш-код, то они гарантированно различаются. Вероятность возникновения коллизий играет немаловажную роль в оценке качества хеш-функций. Для того чтобы коллизии не замедляли работу с таблицой существуют
Определение: |
— называется хеш-функцией, где множество хранит ключи из множества . Если значит Коллизия: | — множество объектов (универсум).
Виды хеширования
- По способу хранения:
- Статическое — фиксированное количество элементов. Один раз заполняем хеш-таблицу и осуществляем только проверку на наличие в ней нужных элементов.
- Динамическое — добавляем, удаляем и смотрим на наличие нужных элементов.
- По виду хеш-функции:
- Детерминированная хеш-функция.
- Случайная хеш-функция.
Свойства хеш-таблицы
На поиск элемента в хеш-таблице в худшем случае, может потребоваться столько же времени, как и в списке, а именно перехешировать таблицу: увеличить размер массива и заново добавить в новую хеш-таблицу все пары.
, но на практике хеширование более эффективно. При некоторых разумных допущениях математическое ожидание времени поиска элемента в хеш-таблице составляет . А все операции (поиск, вставка и удаление элементов) в среднем выполняются за время . При этом не гарантируется, что время выполнения отдельной операции мало́, так как при достижении некоторого значения коэффициента заполнения необходимоХеширование в современных языках программирования
Почти во всех современных языках присутствуют классы, реализующие хеширование. Рассмотрим некоторые из них.
- Java
- HashMap — реализация интерфейса ассоциативного массива с использованием хеш-таблицы,
- HashSet — реализация интерфейса множества с использованием хеш-таблицы,
- LinkedHashMap — потомок класса HashMap. Позволяет просматривать значения в том порядке, в котором они были добавлены.
- C++
- hash_map — реализация интерфейса ассоциативного массива с использованием хеш-таблицы,
- hash_set — реализация интерфейса множества с использованием хеш-таблицы.
Примечания
- ↑
где — количество элементов в хеш-таблице, а — её размер. - ↑ Парадокс дней рождения — Википедия
Источники информации
- Томас Кормен, Чарльз Лейзерсон, Рональд Ривест, Клиффорд Штайн. «Алгоритмы. Построение и анализ» — «Вильямс», 2011 г. — 1296 стр. — ISBN 978-5-8459-0857-5, 5-8459-0857-4, 0-07-013151-1
- Дональд Кнут. «Искусство программирования, том 3. Сортировка и поиск» — «Вильямс», 2007 г. — 824 стр. — ISBN 0-201-89685-0
- Хеш-таблица — Википедия