Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
15
Добавлен:
31.03.2015
Размер:
115.2 Кб
Скачать

Пример результата просеивания

Возьмем массив [1,7,5,4,9,8,12,11,2,10,3,6] (N = 12).

Его исходное состояние таково (серым цветом выделено "основание" пирамиды, не требующее просеивания):

1

7

5

4

9

8

12

11

2

10

3

6

После первых трех просеиваний (a[6], a[5], a[4]) получим такую картину (здесь и далее серым цветом выделяем участников просеивания):

1

7

5

4

9

8

12

11

2

10

3

6

1

7

5

11

10 9

8

12

11

2

9 10

3

6

1

7

5

11 4

10

8

12

4 11

2

9

3

6

Просеивание двух следующих элементов (a[3] и a[2]) тоже не вызовет вопросов - для каждого из них будет достаточно только одного шага:

1

7

12 5

11

10

8

5 12

4

2

9

3

6

1

11 7

5

7 11

10

8

12

4

2

9

3

6

А вот для просеивания последнего элемента (a[1]) понадобится целых три шага:

12 1

11

1 12

7 1

10

8

5

4

2

9

3

6

12

11

8 1

7

10

1 8

5

4

2

9

3

6

12

11

8

7

10

6 1

5

4

2

9

3

1 6

Итак, мы превратили исходный массив в пирамиду: в любой тройке a[i], a[2*i] и a[2*i+1] максимум находится "сверху".

Алгоритм УлПир

Для того чтобы отсортировать массив методом Пирамиды, необходимо выполнить такую последовательность действий:

0-й шаг: Превратить исходный массив в пирамиду (с помощью просеивания).

1-й шаг: Для N-1 элементов, начиная с последнего, производить следующие действия:

поменять местами очередной "рабочий" элемент с первым;

просеять (новый) первый элемент, не затрагивая, однако, уже отсортированный хвост последовательности (элементы с i-го по N-й).

Реализация алгоритма УлПир

Часть программы, реализующую нулевой шаг алгоритма УлПир, мы привели в пункте "Просеивание", поэтому здесь ограничимся только реализацией основного шага 1:

for i:= N downto 2 do

begin x:= a[1];

a[1]:= a[i];

a[i]:= x;

j:= 1;

while j<=((i-1)div 2) do

begin k:= 2*j;

if (k+1<=i-1) and (a[k]<a[k+1])

then k:= k+1;

if a[k]>a[j]

then begin x:= a[j];

a[j]:= a[k];

a[k]:= x;

j:= k

end

else break

end

end;

Эффективность алгоритма УлПир

Пирамидальная сортировка хорошо работает с большими массивами, однако на маленьких примерах (N<20) выгода от ее применения может быть не слишком очевидна.

В среднем этот алгоритм имеет сложность, пропорциональную N*log N.

Быстрая сортировка

Алгоритм Быстр

Возьмем в сортируемом массиве срединный элемент: x:=a[(1+N)div 2] ;

Будем производить следующие действия:

начав с левого конца массива, будем перебирать его компоненты до тех пор, пока не встретим элемент a[i], больший х ;

начав с правого конца массива, будем перебирать его компоненты до тех пор, пока не встретим элемент a[j], меньший х ;

поменяем местами элементы a[i] и a[j] ;

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

Теперь применим эти же действия к левой и к правой части массива - рекурсивно.

22 Рекурсия: принципы действия и использования, примеры программ

Рекурсивным назыв. объект, частично состоящий, или определяемый через самого себя (или с помощью самого себя). Гл. достоинство рекурсии – она позволяет с помощью конечного высказывания определить бесконечное множество объектов. С т. з. прогр-я, с помощью конечной рекурсивной программы можно опр. бесконечные вычисления, причем программа не будет содержать явных повторов.

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

Программа называется прямо рекурсивной, если она содержит явную ссылку на себя. Если процедура P ссылается на себя через некоторую процедуру Y, то она называется косвенно рекурсивной. Аналогично операторам цикла рекурсивные процедуры могут приводить к не заканчивающимся вычислениям. Т.е. рекурсивные обращения к процедуре должны управляться некоторым условием, которое в определённый момент становится ложным.

Главная проблема рекурсии – каждая рекурсивная активация процедуры требует памяти для хранения промежуточных значений всех её переменных. Необходимо убедиться в том, что глубина рекурсии не только конечна, но и мала. При большой глубине рекурсии и неправильно написанной программе возможен выход с системной ошибкой. function Factor_rek (i:integer):integer;

begin

if i<= 0 then

Factor_rek = 1

Else Factor_rek:= i*Factor_rek(i - 1);

end;

function iter (i:integer):integer;

begin

if i<= 0 then

iter = 1

Else

Begin

K:=0;

F:=0;

While k<i do

Begin

k:=k+1;

f:=k*f;

end;

iter:=f;

end;

end.

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

23 Быстрая сортировка , примеры алгоритмов и программ.

Идея: среди n значений случ. выбир. барьерный. Затем в начало массива помещаются все эл-ты < барьера, а в конец - >. На каждом из подмножеств операция рекурсивно повторяется до тех пор, пока не образуются подмн, сост.из1 или2 эл-тов. Массив отсортирован.

Недостаток: барьерный эл-т не остаётся на месте, участвует в дальнейшей обработке массива.

Procedure qsort_2(low,high:integer);

Begin

If low >=high then Exit;

If(high-low=l) then

Begin

If a[low]>a[high] then

Begin

t:=a[low];

a[low] :=a[high];

a[high]:=t;

end;

end else

begin

part:=(low +high) div 2;

x:=a[part];

i:=low; j:=high;

repeat

begin

while a[i]<x do i:=i+l;

while a(j]>x do j:=j-l;

if i<=j then

begin

t:=a[i];

a[i]:=a[j];

a[j]:=t;

i:=i+l;j:=j-l; end;

until i>j;

if low<j then QSORT_2(low,j);

if i< high then QSORT_2(I,high);

end;

end;

24 НАХОЖДЕНИЕ МЕДИАНЫ МАССИВА.

Медианой для n элементов явл. эл-т, < или = половине из n эл-тов и>или= др. половине. Нужно отсортировать массив по методу Qsort.

Сначала применяется операция разделения i=1,r=n для k=n/2. В рез-те получим индексы i и j, удовлетворяющие условиям:

1.A(k)<x для всех h<i

2.A(k)>x для всех h>j

3.i>j где x=A(k)

При этом возможны 3 варианта результата разделения:

разделяющее значение слишком мало и граница лежит ниже нужного значения k. Процесс разделения продолжают для элементов A(i)-A(h)

разделяющее значение слишком велико и граница лежит выше нужного значения k. Процесс разделения продолжают для A(i)=A(j)

элемент A(k) выбран правильно.

Процесс разделения продолжают до тех пор, пока не возникнет 3 случай.

Недостаток: исходный массив видоизменяется, т.к. имеют место перестановки.

25 СРАВНЕНИЕ МЕТОДОВ СОРТИРОВКИ

В данном разделе мы сравним описанные алгоритмы сортировки: вставками, Шелла и быструю сортировку. Есть несколько факторов, влияющих на выбор алгоритма в каждой конкретной ситуации:

  • Устойчивость. Напомним, что устойчивая сортировка не меняет взаимного расположения элементов с равными ключами. Сортировка вставками - единственный из рассмотренных алгоритмов, обладающих этим свойством.

  • Память. Сортировке на месте не требуется дополнительная память. Сортировка вставками и Шелла удовлетворяют этому условию. Быстрой сортировке требуется стек для организации рекурсии. Однако, требуемое этому алгоритму место можно сильно уменьшить, повозившись с алгоритмом.

  • Время. Время, нужное для сортировки наших данных, легко становится астрономическим (см. таблицу 1.1). Таблица 2.2 позволяет сравнить временные затраты каждого из алгоритмов по количеству исполняемых операторов. Время, затраченное каждым из алгоритмов на сортировку случайного набора данных, представлено в таблице 2.3.

 

Метод

С

М

1

Insert

(N2+n-2)/4

(N2-9N-10)/4

2

Select

(N2-N)/2

N(lnN+0,57)

3

Exchange

(N2-N)/2

(N2-N)*0,75

26 Поиск информации в массиве

Линейный поиск – используется, когда нет никакой дополнительной информации о разыскиваемых данных.

Соседние файлы в папке Информатика (1 семестр) (билеты)