logo
УП_САОД_2003

Последовательный (линейный) поиск

Последовательный поиск – самый простой из известных. Суть его заключается в следующем. Множество элементов просматривается последовательно в некотором порядке, гарантирующем, что будут просмотрены все элементы множества (например, слева направо). Если в ходе просмотра множества будет найден искомый элемент, просмотр прекращается с положительным результатом; если же будет просмотрено все множество, а элемент не будет найден, алгоритм должен выдать отрицательный результат.

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

Оформим описанный алгоритм в виде функции на Паскале.

function LineSearch(Key: ItemType, n: integer;

var A: array[1..n] of ItemType): boolean;

{Функция линейного поиска,}

{если элемент найден, то возвращает значение true, иначе - false}

var

i: integer;

begin

i := 1;

while (i <=n ) and (A[i]<>Key) do i := i + 1;

if A[i]=Key then LineSearch := true

else LineSearch := false;

end;

В среднем этот алгоритм требует n/2 итераций цикла. Это означает временную сложность алгоритма поиска пропорциональную O(n). Никаких ограничений на порядок элементов в массиве данный алгоритм не накладывает. При наличии в массиве нескольких элементов со значением Key алгоритм находит только первый из них (с наименьшим индексом).

Здесь можно хранить множество как в массиве (как показано выше), так и в обычном однонаправленном списке.

Существует модификация алгоритма последовательного поиска, которая ускоряет поиск.

Эта модификация поиска является небольшим усовершенствованием предыдущего. В любой программе, имеющей циклы, наибольший интерес представляет оптимизация именно циклов, то есть сокращение числа действий в них. Посмотрим на алгоритм последовательного поиска. В цикле while производится два сравнения: (i<=n) и (A[i]<>Key). Избавимся от одного из них (от первого), введя в массив так называемый «барьер» положив A[n+1] := Key. В этом случае в цикле обязательно будет найден элемент со значением Key. После завершения цикла требуется дополнительная проверка того, был ли найден искомый элемент или «барьер».

Тогда функция поиска будет выглядеть так:

function LineSearchWithBarrier(Key: ItemType, n: integer;

var A: array[1..n+1] of ItemType): boolean;

{Функция линейного поиска с барьером,}

{если элемент найден, то возвращает значение true, иначе - false}

var

i: integer;

begin

i := 1;

A[n+1] := Key;

while A[i]<>Key do i := i + 1;

if i <= n then LineSearchWithBarrier := true

else LineSearchWithBarrier := false;

end;

Надо сказать, что хотя такая функция будет работать быстрее, но временная сложность алгоритма остается такой же – O(n). Гораздо больший интерес представляют методы, не только работающие быстро, но и реализующие алгоритмы с меньшей сложностью. Один из таких методов – бинарный поиск.