- •Связывание
- •Преимущества и недостатки связывания
- •Хранение хеш‑таблиц на диске
- •Удаление элементов
- •Преимущества и недостатки применения блоков
- •Открытая адресация
- •Линейная проверка
- •Первичная кластеризация
- •Упорядоченная линейная проверка
- •Квадратичная проверка
- •Удаление элементов
- •Рехеширование
- •Изменение размера хеш‑таблиц
Упорядоченная линейная проверка
При выполнении поиска в упорядоченном списке методом полного перебора, можно остановить поиск, если найдется элемент со значением большим, чем искомое. Так как при этом возможное положение искомого элемента уже позади, значит искомый элемент отсутствует в списке.
Можно использовать похожую идею при поиске в хеш‑таблице. Предположим, что можно организовать элементы в хеш‑таблице таким образом, что значения в каждой тестовой последовательности находятся в порядке возрастания. Тогда при выполнении тестовой последовательности во время поиска элемента можно прекратить поиск, если встретится элемент со значением, большим искомого. В этом случае позиция, в которой должен был бы находиться искомый элемент, уже осталась позади, и значит элемента нет в таблице.
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 = UNUSED Or probes > NumEntries Then
LocateItem = HASH_NOT_FOUND
pos = -1
Exit Function
End If
' Элемент найден или его нет в таблице.
If new_value >= Value Then Exit Do
pos = (pos + 1) Mod NumEntries
probes = probes + 1
Loop
If Value = new_value Then
LocateItem = HASH_FOUND
Else
LocateItem = HASH_NOT_FOUND
End If
End Function
Для того, чтобы этот метод работал, необходимо организовать элементы в хеш‑таблице так, чтобы при выполнении тестовой последовательности они встречались в возрастающем порядке. Существует достаточно простой метод вставки элементов, который гарантирует такое расположение элементов.
Когда в таблицу вставляется новый элемент, для него выполняется тестовая последовательность. Если найдется свободная ячейка, то элемент вставляется в эту позицию и процедура завершена. Если встречается элемент, значение которого больше значения нового элемента, то они меняются местами и продолжается выполнение тестовой последовательности для большего элемента. При этом может встретиться элемент с еще большим значением. Тогда элементы снова меняются местами, и выполняется поиск нового местоположения для этого элемента. Этот процесс продолжается до тех пор, пока, в конце концов, не найдется свободная ячейка, при этом возможно несколько элементов меняются местами.
Public Function InsertItem(ByVal Value As Long, pos As Integer,_ probes As Integer) As Integer
Dim new_value As Long
Dim status As Integer
' Проверить, заполнена ли таблица.
If m_NumUnused < 1 Then
' Поиск элемента.
status = LocateItem(Value, pos, probes)
If status = HASH_FOUND Then
InsertItem = HASH_FOUND
Else
InsertItem = HASH_TABLE_FULL
pos = -1
End If
Exit Function
End If
probes = 1
pos = (Value Mod m_NumEntries)
Do
new_value = m_HashTable(pos)
' Если значение найдено, поиск завершен.
If new_value = Value Then
InsertItem = HASH_FOUND
Exit Function
End If
' Если ячейка свободна, элемент должен находиться в ней.
If new_value = UNUSED Then
m_HashTable(pos) = Value
HashForm.TableControl(pos).Caption = Format$(Value)
InsertItem = HASH_INSERTED
m_NumUnused = m_NumUnused - 1
Exit Function
End If
' Если значение в ячейке таблицы больше значения
' элемента, поменять их местами и продолжить.
If new_value > Value Then
m_HashTable(pos) = Value
Value = new_value
End If
pos = (pos + 1) Mod NumEntries
probes = probes + 1
Loop
End Function
Программа Orderedв архиве с примерами демонстрирует открытую адресацию с упорядоченной линейной проверкой. Она идентична программеLinear, но использует упорядоченную хеш‑таблицу.
В обоих методах для вставки нового элемента требуется примерно одинаковое число шагов. Чтобы вставить элемент Kв таблицу, каждый из методов начинает с позиции(K Mod NumEntries)и перемещается по таблице до тех пор, пока не найдет свободную ячейку. Во время упорядоченного хеширования может потребоваться поменять вставляемый элемент на другие в его тестовой последовательности. Если элементы представляют собой записи большого размера, то на это может потребоваться больше времени, особенно если записи находятся на диске или каком‑либо другом медленном запоминающем устройстве.
Упорядоченная линейная проверка определенно является лучшим выбором, если вы знаете, что программе придется совершать большое число безуспешных операций поиска. Если программа будет часто выполнять поиск элементов, которых нет в таблице, или элементы таблицы имеют большой размер и перемещать их достаточно сложно, то можно получить лучшую производительность при использовании неупорядоченной линейной проверки.