Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Презентации 2часть / Лекция_21_Поиск и сортировка.ppt
Скачиваний:
26
Добавлен:
11.05.2015
Размер:
115.71 Кб
Скачать

Поиск с барьером

Единственная возможность – попытаться упростить логическое

выражение, ограничившись одной проверкой в цикле с помощью введения вспомогательного элемента - барьера, который предохраняет от перехода за пределы массива

a[n+1].k=x; i=1;

While a[i].k<>x do i:=i+1;

if i=n+1 then элемент не найден

else элемент i’;

Эффективность этого алгоритма в два раза выше предыдущего, и оценивается как О(n/2).

07/02/19

11

Основная идея алгоритма поиска делением пополам в упорядоченном массиве

a[1]< a[2]< a[..]< a[..]< a[m]< a[m+1] <a[..]< a[..]< a[n]

Возьмем «средний» (m) элемент.

Если a[m].k<x то все элементы i<=m можно исключить из дальнейшего поиска,

если a[m].k x то можно исключить все i>m:

07/02/19

12

Алгоритм поиска делением пополам

используется, когда данные упорядочены по возрастанию ключа k, т.е. a[i].k<a[i+1].k.

i=1; j:=N;

While i<j do

begin

m:=(i+j) div 2;

if a[m].k<x then i:=m+1

else j:=m

 

end;

 

if a[i].k=x then элемент i найден

 

else нет;

 

 

07/02/19

13

Особенность

В этом алгоритме отсутствует внутри цикла проверка совпадения a[m].k=x.

На первый взгляд это кажется странным, однако тестирование показывает, что в среднем, выигрыш от уменьшения количества проверок превосходит потери от нескольких «лишних» вычислений до выполнения условия i=j.

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

Poisk(a[1]..a[n])= if a[m].k<x then Poisk(a[1]..a[n/2])

 

else Poisk(a[n/2+1]..a[n])

07/02/19

14

Рекурсивная реализация двоичного поиска

Function Poisk(var a:mas;n:word;x:Tk): word;

Function Del(L,R:word):word;

var m:word;

begin

if R<=L then Del:=R

else begin

m:=(L+R)div 2;

if a[m].k<x then Del:=Del(m+1,R)

else Del:=Del(L,m);

end;

end; // Del

var i:word;

begin

i:=Del(1,n);

if a[i].k=x then Result:=i //поиск успешен

else Result:=0; //нет элемента

end; //Poisk

07/02/19

15

Трассировка алгоритма

• Исходный массив

a1..a7= 1 2 3 5 7 8 9; x=8

M=4 L=5 R=7

7 8

9

M=6 L=5 R=6

7 8

 

M=5 L=6 R=6

L=R L=6

• Результат i=6

ai=8=x

07/02/19

16

Трассировка алгоритма

• Исходный массив

 

 

a1..a7= 1 2 3 5 7 8 9;

x=4

1 2 3 5

M=4 L=1 R=4

 

3 5

M=2 L=3 R=4

M=3 L=4 R=4

L=R

i=4

ai=5 x

• Результат i=0 (элемент отсутствует)

07/02/19

17

Эффективность двоичного поиска

Легко подсчитать, что эффективность этого алгоритма оценивается как

2m=n m=log2n

это обозначается как О(lоg2n).

Т.е. для n=128 log2128=7 128/2/7 9

этот метод в 9 раз эффективнее линейного поиска с барьером

для n=1024 – в 50 раз,

для n=106 в 2500 раз.

07/02/19

18

Сортировка массивов

Под сортировкой понимается процесс перегруппировки элементов массива приводящий к их упорядоченному расположению относительно ключа.

Цель сортировки – облегчить последующий поиск элементов.

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

07/02/19

19

Методы внутренней сортировки массивов характеризуются тем, что все перестановки элементов должны выполняться «на том же месте» в исходном массиве без привлечения доп. массивов. Это эффективно, если имеется прямой доступ к записи через индекс.

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

Следует отметить, что при использовании дополнительных массивов эффективность сортировки обычных индексированных массивов можно значительно повысить.

07/02/19

20