Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
nestudent.ru_46905.doc
Скачиваний:
22
Добавлен:
12.09.2019
Размер:
2.07 Mб
Скачать

Квадратичная проверка

Один из способов уменьшить первичную кластеризацию состоит в том, чтобы использовать хеш‑функцию следующего вида:

Hash(K, P) = (K + P2) Mod N где P = 0, 1, 2, ...

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

=======302

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

Следующий код демонстрирует поиск элемента с использованием квадратичной проверки (quadratic probing):

Public Function LocateItem(Value As Long, pos As Integer, probes As Integer) As Integer

Dim new_value As Long

probes = 1

pos = (Value Mod m_NumEntries)

Do

new_value = m_HashTable(pos)

' Элемент найден.

If new_value = Value Then

LocateItem = HASH_FOUND

Exit Function

End If

' Элемента нет в таблице.

If new_value = UNUSED Or probes > NumEntries Then

LocateItem = HASH_NOT_FOUND

pos = -1

Exit Function

End If

pos = (Value + probes * probes) Mod NumEntries

probes = probes + 1

Loop

End Function

Программа Quad демонстрирует открытую адресацию с использованием квадратичной проверки. Она аналогична программе Linear, но использует квадратичную, а не линейную проверку.

В табл. 11.3 приведена средняя длина тестовых последовательностей, полученных в программах Linear и Quad для хеш‑таблицы со 100 ячейками, значения элементов в которой находятся в диапазоне от 1 до 999. Квадратичная проверка обычно дает лучшие результаты.

@Рис. 11.8. Квадратичная проверка

======303

@Таблица 11.3. Длина поиска при использовании линейной и квадратичной проверки

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

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

3

3 + 12 = 4 = 4 (Mod 6)

3 + 22 = 7 = 1 (Mod 6)

3 + 32 = 12 = 0 (Mod 6)

3 + 42 = 19 = 1 (Mod 6)

3 + 52 = 28 = 4 (Mod 6)

3 + 62 = 39 = 3 (Mod 6)

3 + 72 = 52 = 4 (Mod 6)

3 + 82 = 67 = 1 (Mod 6)

3 + 92 = 84 = 0 (Mod 6)

3 + 102 = 103 = 1 (Mod 6)

и так далее.

Эта тестовая последовательность обращается к позициям 1 и 4 дважды перед тем, как обратиться к позиции 3, и никогда не попадает в позиции 2 и 5. Чтобы пронаблюдать этот эффект, создайте в программе Quad хеш‑таблицу с шестью ячейками, а затем вставьте элементы 1, 3, 4, 6 и 9. Программа определит, что таблица заполнена целиком, хотя две ячейки и остались неиспользованными. Тестовая последовательность для элемента 9 не обращается к элементам 2 и 5, поэтому программа не может вставить в таблицу новый элемент.

=======304

Можно показать, что квадратичная тестовая последовательность будет обращаться, по меньшей мере, к N/2 ячеек таблицы, если размер таблицы N — простое число. Хотя при этом гарантируется некоторый уровень производительности, все равно могут возникнуть проблемы, если таблица почти заполнена. Так как производительность для почти заполненной таблицы в любом случае сильно падает, то возможно лучше будет просто увеличить размер хеш-таблицы, а не беспокоиться о том, сможет ли тестовая последовательность найти свободную ячейку.

Не столь очевидная проблема, которая возникает при применении квадратичной проверки, заключается в том, что хотя она устраняет первичную кластеризацию, во время нее может возникать похожая проблема, которая называется вторичной кластеризацией (secondary clustering). Если два элемента отображаются в одну ячейку, для них будет выполняться одна и так же тестовая последовательность. Если множество элементов отображаются на одну из ячеек таблицы, они образуют вторичный кластер, который распределен по хеш‑таблице. Если появляется новый элемент с тем же самым начальным значением, для него приходится выполнять длительную тестовую последовательность, прежде чем он обойдет элементы во вторичном кластере.

На рис. 11.9 показана хеш‑таблица, которая может содержать 10 ячеек. В таблице находятся элементы 2, 12, 22 и 32, которые все изначально отображаются в позицию 2. Если попытаться вставить в таблицу элемент 42, то нужно будет выполнить длительную тестовую последовательность, которая обойдет все эти элементы, прежде чем найдет свободную ячейку.

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