Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Baknell_Fundamentalnyie_algoritmyi_i_strukturyi...rtf
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
3.86 Mб
Скачать

Разрешение конфликтов посредством линейного зондирования

Если количество элементов, которые, скорее всего, должна содержать хеш‑таблица, известно, можно выделить место для хеш‑таблицы, содержащей это количество элементов и небольшое число свободных ячеек "на всякий случай". Было разработано несколько алгоритмов, которые позволяют хранить элементы в таблице, используя пустые ячейки таблицы для хранения элементов, которые конфликтуют с уже имеющимися. Этот класс алгоритмов называют схемами с открытой адресацией (open‑addressing schemes). Простейшая схема с открытой адресацией ‑ это линейное зондирование (linear probing).

Поясним это на простом примере. Предположим, что мы вставляем фамилии в хеш‑таблицу. До сих пор еще не описывалось, как выглядит хеш‑таблица, но пока будем считать, что она представляет собой простой массив указателей элементов. Предположим, что существует функция хеширования того или иного вида.

Для начала вставим в пустую хеш‑таблицу фамилию "Smith" (т.е. вставим элемент, ключом которого является "Smith"). Выполним хеширование ключа Smith с помощью функции хеширования и получим значение индекса, равное 42. Установим значение 42‑го элемента хеш‑таблицы равным Smith. Теперь записи хеш‑таблицы вблизи этого элемента выглядят следующим образом:

Элемент 41: <пусто>

Элемент 42: Smith

Элемент 43: <пусто>

Это было достаточно просто. Теперь вставим фамилию "Jones". Необходимо выполнить те же действия, что и в предыдущем случае: следует вычислить хеш‑значение ключа Jones, а затем вставить значение Jones по результирующему индексу. К сожалению, используемая функция хеширования имеет неизвестное происхождение и для фамилии Jones генерирует хеш‑значение, которое также равно 42. Если теперь обратиться к хеш‑таблице, выясняется, что имеет место конфликт: ячейка 42 уже занята фамилией Smith. Что же делать? Используя линейное зондирование, мы проверяем следующую ячейку, чтобы выяснить, пуста ли она. Если да, то мы устанавливаем значение 43‑го элемента хеш‑таблицы равным Jones. (Если бы 43‑я ячейка оказалась занятой, пришлось бы проверить следующую ячейку и т.д., возвращаясь к началу хеш‑таблицы по достижении ее конца. Со временем мы нашли бы пустую ячейку либо вернулись бы к исходному состоянию, выяснив, что таблица заполнена.) Действие по проверке ячейки в хеш‑таблице называется зондированием (probing), отсюда и название самого алгоритма ‑ линейное зондирование.

Теперь хеш‑таблица вблизи интересующей нас области выглядит следующим образом:

Элемент 41: <пусто>

Элемент 42: Smith

Элемент 43: Jones

Элемент 44: <пусто>

Вставив два элемента в гипотетическую хеш‑таблицу, посмотрим, можно ли их снова найти. Выполним расчет хеш‑значения для "Smith", в результате чего получаем индекс, равный 42. Обратившись к 42‑му элементу, мы видим, что элемент Smith находится именно здесь. Выполнив расчет хеш‑значения для Jones и получив индекс, равный 42, обратимся к 42‑й ячейке. В ней находится элемент Smith, являющийся не тем, который мы ищем. Теперь нужно поступить так же, как и при вставке: обратиться к следующему элементу хеш‑таблицы для выяснения того, совпадает ли он с искомым. В данном случае это так.

А как насчет поиска элемента, который отсутствует в таблице? Выполним поиск элемента "Brown". Реализуем хеширование, в результате чего будет получено значение индекса, равное 43. При обращении к 43‑му элементу выясняется, что он соответствует элементу Jones. При переходе к следующему, 44‑му, элементу выясняется, что он пуст. Теперь можно сделать вывод, что элемент Brown в хеш‑таблице отсутствует.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]