
- •§12 Алгоритмы поиска элементов во множестве.
- •1. Последовательный поиск
- •2. Бинарный поиск
- •3. Деревья бинарного поиска
- •§13 Абстрактные типы данных. Методы представления множеств.
- •1. Реализация атд «множество» посредством двоичных векторов
- •2. Реализация атд «множество» с помощью массивов
- •3. Реализация атд «множество» посредством связанных списков
- •§14. Реализация атд «Словарь». Хеширование.
- •1. Открытое хеширование
- •2. Закрытое хеширование.
- •2.2. «Случайные» методики повторного хеширования
§12 Алгоритмы поиска элементов во множестве.
Рассмотрим
задачу поиска в конечном множестве
,
называемом таблицей элементов, элемента,
удовлетворяющего некоторому условию.
Пусть
,
-некоторое
универсальное множество с заданным на
нем линейным
порядком
т.е. отношением «< », которое:
Антисимметрично:
из
и
Транзитивно: из и
Связано:
или
или
.
1. Последовательный поиск
Линейный, последовательный поиск — алгоритм нахождения заданного элемента z поочередным сравнением с элементами таблицы в том порядке, в котором они расположены.
Данный алгоритм является простейшим алгоритмом поиска, не накладывает никаких ограничений на таблицу и имеет простейшую реализацию.
В худшем случае потребуется просмотр всей таблицы для отыскания элемента z или установления, что z в таблице отсутствует. Таким образом, эффективность линейного поиска равна O(n), где n=|T|. Это является основным недостатком алгоритма. В связи с малой эффективностью по сравнению с другими алгоритмами поиска линейный поиск обычно используют только если таблица содержит мало элементов. Тем не менее, преимуществом линейного поиска является то, что он не требует дополнительной памяти или обработки/анализа таблицы, так что может работать в потоковом режиме при непосредственном получении данных из любого источника.
Далее приведена процедура, реализующая линейный поиск элемента z в таблице (одномерном массиве) Т. Переменные L и R содержат, соответственно, левую и правую границы отрезка массива, где ищется нужный элемент. Исследования начинаются с первого элемента отрезка. Если этот элемент не совпадает с искомым z, осуществляется переход к следующему элементу. Таким образом, в результате каждой проверки область поиска уменьшается на один элемент.
begin
T[R+1]:=z;
x:= L;
(3)while T[x] <> z do x := x + 1;
(4) if x < R+1 then return x; // элемент найден в позиции x
(5) else return -1; // элемент не найден
end;
Использован цикл while, т.к. в цикле со счетчиком по x при каждом прохождении тела цикла требуется проверка условия окончания цикла x=R.
Для гарантированного выхода из цикла на R+1 – ом шаге в таблицу добавлен элемент T[R+1]:=z.
2. Бинарный поиск
Бинарный поиск возможен, когда элементы в таблице упорядочены и ячейки таблицы распределены последовательно в памяти с произвольным доступом.
Поиск
элемента
в отрезке
:
-
Новый индекс
для «средней точки» устанавливается в
середине отрезка
(это
дает самый эффективный алгоритм).
-
Если
,
то поиск продолжается на отрезке [b,
c-1];
-
Если
,
то далее ищем в отрезке [c+1,
e];
-
Если
,
то искомый элемент найден и поиск
завершен.
begin
(1) b:=1;
(2) e:=n;
(3) while b<=e do begin
(4) c:=(b+e) div 2;
(5) if T[c]>z then e:=c-1;
(6) else if T[c]<z then b:=c+1;
(7) else return c;
end;
(8) return «не найдено»;
end
Рассмотрим сложность алгоритма бинарного поиска.
Тело цикла (4)-(7) требует времени О(1).
Оценим
количество итераций цикла (3)-(7),
предполагая, что длина отрезка является
степенью двойки:
.
(В остальных случаях сложность алгоритма
можно оценить исходя из Замечания 1 §
6)
-После
первой итерации длина рассматриваемого
отрезка равна
.
-После
второй итерации -
.
……………………………………
-После
k-й
итерации -
.
Это означает, что b=e.
Далее, в строке (4) получим с=b=e,
и если искомый элемент всё же не будет
найден (строка (7)), то операции в строке
(5) или (6) приведут к условию b>e,
и цикл закончит работу.
Таким
образом, количество итераций цикла
(3)-(7) равно
.
Время выполнения цикла (3)-(7) равно
Таким
образом сложность алгоритма равна
.