Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
САОД / САОД1 / Лабораторная работа 1.doc
Скачиваний:
17
Добавлен:
26.04.2015
Размер:
64 Кб
Скачать

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

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

Оформим описанный алгоритм в виде кусочка программы на Паскале и C. Пусть множество хранится в первых n элементах массива A. При этом не важен тип элементов множества, важна лишь возможность проверки эквивалентности элемента множества искомому элементу Key:

Пример на языке Паскаль:

i:= 1;

while (i<=n)and(A[i]<>Key) do Inc(i);

if A[i]=Key then <элемент найден>

else<элемент не найден>;

Пример на языке С:

i=1;

while ((i<=n)&&(A[i]!=Key)) i++;

if (A[i]==Key) <элемент найден>;

else <элемент не найден>;

В среднем этот алгоритм требует n/2 итераций цикла. Это означает сложность алгоритма поиска T(n). Единственное требование к способу хранения множества – существование некоторого порядка на множестве: чтобы можно было указать, что один элемент предшествует другому. Здесь можно хранить множество как в массиве (рассмотренный выше кусок программы), так и в обычном однонаправленном списке:

Пример на языке Паскаль:

Type

TListItem=record

Item: TItem;

Next: ^ListItem;

end;

Пример на языке С:

struct TListItem

{

TItem Item;

TListItem *Next;

};

Рассмотрим добавление элемента Key во множество, хранимое в виде массива. Здесь достаточно просто дописать новый элемент в “конец” множества:

Пример на языке Паскаль:

Inc(n);

A[n] :=Key;

Пример на языке С:

n++;

A[n]=Key;

Удалению элемента всегда предшествует успешный поиск. Это значит, что сложность операции удаления не может быть меньше сложности операции поиска. В данном случае при удалении нам придется сначала найти положение удаляемого элемента, затем все элементы, следующие за ним, сдвинуть на одну позицию к началу массива и уменьшить n. То есть в любом случае надо пробежать весь массив от начала до конца (это означает сложность T(n)):

Пример на языке Паскаль:

i:= 1;

while (i<=n)and(A[i]<>Key) do Inc(i); {поиск}

if A[i]=Key then

begin

while i<n do

begin

A[i] := A[i+1]; {сдвигаем}

Inc(i);

end;

Dec(n);

end;

Пример на языке С:

i=0;

while ((i<=n)&&(A[i]!=Key)) i++; //Поиск

if (A[i]==Key)

{

while (i<n)

{

A[i]=A[i+1]; //Сдвигаем

i++;

}

n--;

}

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