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

Анализ алгоритма сортировки обменами

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

Для обоснования алгоритма сортировки необходимо доказать, что алгоритм всегда (независимо от входа) завершает свою работу и его результат - упорядо­чен­ный по возрастанию массив. Оценка сложности (эффективности) алгоритма по вре­мени заключается в нахождении C(n), M(n) в худшем случае, в среднем. Поскольку алгоритм сортирует массив “на месте”, его сложность по памяти - константа.

К другим свойствам алгоритма можно отнести свойство устойчивости. (Алгоритм сорти­ров­ки называется устойчивым, если он не переставляет местами равные элементы.) Осуществим анализ алгоритма сортировки обменами.

Завершаемость

Алгоритм BublSort всегда завершает свою работу, поскольку он использует только циклы с параметром, и в теле циклов параметры принудительно не изменяются.

Корректность

Внутренний цикл алгоритма (с параметром j) осуществляет последова­тель­ный просмотр первых i элементов массива. На каждом шаге просмотра сравнива­ются и, если это необходимо, переставляются два соседних элемента. Таким образом, наибольший среди первых i +1 элементов “всплывает” на i +1-ое место. Поэтому после выполнения оператора If имеет место соотношение:

a[j+1] = Max(a[1], ..., a[i], a[j+1])

а после завершения цикла (i = j) имеет место соотношение

a[i+1] = Max(a[1], ..., a[i], a[i+1])

Внешний цикл (с параметром i) управляет длиной просматриваемой части массива: она уменьшается на 1. Поэтому после завершения внутреннего цикла имеет место соотношение: a[i+1]  a[i+2]  ...  a[n] После завершения внешнего цикла получим: а[1]  a[2], a[2]  a[3]  ...  a[n] т.е. массив отсортирован.

Эффективность по времени

Внешний цикл выполнился n-1 раз. Внутренний цикл выполняется i раз (i = n-1, n-2, ..., 1). Каждое выполнение тела внутреннего цикла заключается в одном сра­внении и, возможно, в одной перестановке.

Поэтому

C(n) = 1+2+ ... +n-1 = n*(n-1)/2, M(n)n*(n-1)/2

В худшем случае, когда элементы исходного массива распо­ложены в порядке убывания

C(n) = n*(n-1)/2 = O(n2), M(n)=n*(n-1)/2= О(n2)

Устойчивость

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

Улучшенный алгоритм сортировки обменами

В программе BublSort цикл For используется в качестве внешнего. Это при­водит к тому, что он выполняется ровно n - 1 раз, даже если массив уже упорядочен после нескольких первых проходов. От лишних проходов можно избавиться, применив цикл Repeat и проверяя во внутреннем цикле массив на упорядоченность:

Program BublSort1;

Const n = 100;

Var a : array[1..n] of Real;

i, j : Integer;

b : Real;Flag : Boolean;

Begin

{Блок ввода массива}

i := n - 1;

Repeat

Flag:= True; { признак упорядоченности }

For j := 1 to i do

If a[j] > a[j+1]

then

begin

b := a[j+1]; a[j+1] := a[j]; a[j] := b;

Flag:= False обнаружена “засортировка” (элементы стоят не на своем месте}

end;

i := Pred(i)

until Flag;

{Блок вывода массива}

End.

Этот алгоритм можно еще улучшить, если каждый следующий проход начинать не с начала (j = 1), а с того места, где на предыдущем проходе произошел первый обмен:

{Index : Integer;}

Repeat

Flag:= True; { признак упорядоченности }

Index := 1; { отрезок A[1..Index] упорядочен }

For j := LowIndex to i do

If a[j] > a[j+1]

then

begin

b := a[j+1]; a[j+1] := a[j]; a[j] := b;

If Flag then

begin Index := j; Flag:= False

end

end;

i := Pred(i)

until Flag;

Заметим однако, что наш алгоритм работает несимметрично: если наиболь­ший элемент “всплывет” на свое место за один проход, то наименьший элемент “утонет” на 1-ое место, находясь изначально на n-том месте, за n-1 проход. При этом осуществится максимально возможное число сравнений. Устранить асимметрию можно, чередуя проходы вперед и назад.

Все улучшения рассматриваемого метода относятся к эффективности в среднем. Ни одно из них не уменьшает оценки сложности С(n) в худшем случае.