Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Algoritmy_-_Ekzamen.docx
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
2.13 Mб
Скачать

5. Алгоритмы сортировки массивов за полиномиальное время

Сортировка - процесс перестановки объектов заданной

совокупности в определенном порядке (возрастающем

или убывающем).

Целью сортировки обычно является облегчение последующего

поиска элементов в отсортированном множестве.

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

void sort_by_insertion(key a[] , int N)

{

key x;

int i, j;

for (i=1; i < N; i++)

{

x = a[i] ;

for (j=i-1; (j>=0)&& (x < a[j]); j--)

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

a[j + 1] = x;

}

}

Анализ сортировки простыми вставками

Наихудший случай: упорядоченный в обратном порядке массив

Количество сравнений:

С (N) = 1 + 2 + 3 + ... + N - 1 = (N *(N -1) )/2= О (N2)

Общее время: T(N) = θ(N2)

Сортировка простым обменом. Метод пузырька.

void bubble_sort (key а[] , int N)

{ int i, j;

key x;

for (i=0; i<N-l; i++)

for (j=N-l; j>i; j--)

if (a[j-l] > a[j]) {

x = a [ j ] ; a [ j ] = a [ j -1] ; a [ j -1] = x;

}

}

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

Наихудший случай: упорядоченный в обратном порядке массив

Количество сравнений:

C(N) = (N - 1) + (N - 2) + ... + 1 = (N * (N-1))/2 = O(N2)

Общее время: T(N) = θ(N2)

6. Быстрые алгоритмы сортировки массивов, основанные на сравнении элементов

Хоара:

  1. Разделяем массив на два подмассива [1 ...m] и [m +1 . ..N],

причем

  1. Рекурсивно сортируем получившиеся два подмассива.

Быстрая сортировка использует стратегию Разделяй и властвуй

Выбираем в массиве некоторый элемент, который будем называть опорным элементом. Известные стратегии: выбирать постоянно один и тот же элемент, например, первый, средний или последний по положению; выбирать элемент со случайно выбранным индексом.

Операция разделения массива: реорганизуем массив таким образом, чтобы все элементы, меньшие или равные опорному элементу, оказались слева от него, а все элементы, большие опорного — справа от него.

Два индекса — l и r, приравниваются к минимальному и максимальному индексу разделяемого массива соответственно.

Вычисляется индекс опорного элемента m.

Индекс l последовательно увеличивается до тех пор, пока l-й элемент не превысит опорный.

Индекс r последовательно уменьшается до тех пор, пока r-й элемент не окажется меньше либо равен опорному.

Если r = l — найдена середина массива — операция разделения закончена, оба индекса указывают на опорный элемент.

Если l < r — найденную пару элементов нужно обменять местами и продолжить операцию разделения с тех значений l и r, которые были достигнуты.

Рекурсивно упорядочиваем подмассивы, лежащие слева и справа от опорного элемента.

Базой рекурсии являются наборы, состоящие из одного или двух элементов. Первый возвращается в исходном виде, во втором, при необходимости, сортировка сводится к перестановке двух элементов. Все такие отрезки уже упорядочены в процессе разделения.

Quicksort (int A[], int p, int r){

void quicksort (int а[], int l, int г)

{ int x, w;

int i , j ;

i = 1; j = r;

x = a[(l + r)/2];

do {

while (a[i] < x) i++;

while (x < a[j]) j--;

if (i <= j) {

w = a[i] ;

a [i] = a [j] ;

a[j] = w;

i++;

j--; }

} while (i<=j);

if (l < j) quicksort (a, l, j);

if (i < r) quicksort (a, i, r);

}

int Partition (int A[], int left, int right)

int s= left++;

while(left<=right){

while(A[left]<A[s]) ++left;

while(A[right]>=A[s]) --right;

if (left<right)

Обменять A[left] ↔ A[right];

}

Обменять A[s] ↔ A[right];

return right;

}

Предположим, что все элементы различны.

Наихудший случай: когда при разделении один из массивов не

имеет элементов.

T(n) = T(0) + T(n - 1) + Θ(n)

= Θ(1) + T(n - 1) + Θ(n)

= T(n - 1) + Θ(n)

= Θ(n2)

Анализ быстрой сортировки (наилучший случай)

Наилучший случай: когда при разделении массив разделяется

на равные части.

Т(n) = 2T (n/2) + Θ(n)

= Θ(nlog(n))

Рандомизированная быстрая сортировка

  • Время работы не зависит от порядка элементов во входных данных;

  • Не нужно предположений о распределении входных данных;

  • Нет входных данных, которые приводят к наихудшему случаю;

  • Наихудший случай определяется только генератором

случайных чисел.

Рандомизированная быстрая сортировка

Выбираем граничный элемент случайным образом!

RandomizedPartition (A,p,r)

1 i ← Random(p,r)

2 Обменять A[r] ↔ A[i]

3 return Partition(A,p,r)

RandomizedQuickSort(A,p, r)

1 if p < r

2 then q ← RandomizedPartition(A, p, r)

3 RandomizedQuicksort(A,p,q - 1)

4 RandomizedQuicksort(A, q + 1, r)

Наименьшее время сортировки

Теорема. В любом алгоритме, упорядочивающем с помощью

сравнения пар, на упорядочивание последовательности из N

элементов тратится не меньше c * N * log2N сравнений

при c = 0 и N → .

T(n) > c • N • log2N, при c = 0 и N → ∞

Наименьшее время сортировки. Доказательство

Число перестановок последовательности из N элементов равно N!

Сортировка путем сравнения пар есть спуск по дереву решений –

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

Число сравнений равно высоте разрешающего дерева

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]