Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
22
Добавлен:
26.03.2015
Размер:
231.42 Кб
Скачать
      1. Поиск в связных списках

Поиск методом полного перебора — это единственный способ поиска в связных списках. Так как доступ к элементам возможен только при помощи указателей NextCellна следующий элемент, то необходимо проверить по очереди все элементы с начала списка, чтобы найти искомый.

Так же, как и в случае поиска полным перебором в массиве, если список упорядочен, то можно прекратить поиск, если найдется элемент со значением, большим, чем значение искомого элемента.

Public Function LListSearch(target As Long) As SearchCell

Dim cell As SearchCell

NumSearches = 0

Set cell = ListTop.NextCell

Do While Not (cell Is Nothing)

NumSearches = NumSearches + 1

If cell.Value >= target Then Exit Do

Set cell = cell.NextCell

Loop

If Not (cell Is Nothing) Then

If cell.Value = target Then

Set LListSearch = cell ' Элемент найден.

End If

End If

End Function

Программа Searchв архиве с примерами использует этот алгоритм для поиска элементов в связном списке. Этот алгоритм выполняется немного медленнее, чем алгоритм полного перебора в массиве из-за дополнительных накладных расходов, которые связаны с управлением указателями на объекты. Заметьте, что программаSearchстроит связные списки, только если список содержит не более 10.000 элементов.

Чтобы алгоритм выполнялся немного быстрее, в него можно внести еще одно изменение. Если хранить указатель на конец списка, то можно добавить в конец списка ячейку, которая будет содержать искомый элемент. Этот элемент называется сигнальной меткой(sentinel). Это позволяет обрабатывать особый случай конца списка так же, как и все остальные.

В этом случае, добавление метки в конец списка гарантирует, что в конце концов искомый элемент будет найден. При этом программа не может выйти за конец списка, и нет необходимости проверять условие Not (cell Is Nothing)в каждом циклеWhile.

Public Function SentinelSearch(target As Long) As SearchCell

Dim cell As SearchCell

Dim sentinel As New SearchCell

NumSearches = 0

' Установить сигнальную метку.

sentinel.Value = target

Set ListBottom.NextCell = sentinel

' Найти искомый элемент.

Set cell = ListTop.NextCell

Do While cell.Value < target

NumSearches = NumSearches + 1

Set cell = cell.NextCell

Loop

' Определить найден ли искомый элемент.

If Not ((cell Is sentinel) Or _

(cell.Value <> target)) _

Then

Set SentinelSearch = cell ' Элемент найден.

End If

' Удалить сигнальную метку.

Set ListBottom.NextCell = Nothing

End Function

Хотя может показаться, что это изменение незначительно, проверка Not (cell Is Nothing)выполняется в цикле, который вызывается очень часто. Для больших списков этот цикл вызывается множество раз, и выигрыш времени суммируется. ВVisualBasic, этот версия алгоритма поиска в связных списках выполняется на 20 процентов быстрее, чем предыдущая версия. В программеSearchприведены обе версии этого алгоритма, и вы можете сравнить их.

Некоторые алгоритмы используют потоки для ускорения поиска в связных списках. Например, при помощи указателей в ячейках списка можно организовать список в виде двоичного дерева. Поиск элемента с использованием этого дерева займет время порядка O(log(N)), если дерево сбалансировано. Такие структуры данных уже не являются просто списками, поэтому мы не обсуждаем их в этой главе. Чтобы больше узнать о деревьях, обратитесь к 6 и 7 главам этой книги.