Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Алгоритми та структури даних ЗПІ-91-20210115T104612Z-001 / Лекція 9. Алгоритми сортування.docx
Скачиваний:
47
Добавлен:
15.01.2021
Размер:
96.54 Кб
Скачать

3. Сортування методом обміну (бульбашкове сортування)

Цей алгоритм вважається найпростішим та найчастіше використовуваним для сортування невеликих масивів.

Базовою операцією в ньому є порівняння двох сусідніх елементів масиву. Якщо їх розташування суперечить умові впорядкування, вони міняються місцями. Послідовне застосування такої операції до всіх пар елементів масиву від останньої пари до першої, дозволить виявити найменший елемент в першій позиції. Під час сортування методом обміну впорядкованою буде ліва частина масиву, а щойно описаний процес повторюється для правої частини, котра на кожній ітерації методу зменшуватиметься на один елемент.

Складність алгоритму також О(n2).

Запис алгоритму на псевдокоді

Вхід: масив A з елементів A[1], A[2], ..., A[n-1], A[n]

t := true

цикл поки t:

t := false

цикл для j = 1, 2, ..., n − 1:

якщо A[j] > A[j+1], то:

поміняти місцями елементи A[j] і A[j+1]

t := true

Булева змінна t використовується для того, щоб визначити, чи був виконаний хоч би один обмін на черговій ітерації зовнішнього циклу. Алгоритм зупиняється, коли таких обмінів не було.

Приклад 4. Реалізація алгоритму сортування вибором

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace BoobleSort

{

class Program

{

static void BubbleSort(int[] a)

{

//Сортування обміном (бульбашки)

int temp;

for (int i = 1; i < a.Length; i++)

for (int j = 0; j < a.Length - i; j++)

// сравнить и переставить элементы

if (a[j] >a[j + 1])

{

temp = a[j];

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

a[j + 1] = temp;

}

Console.WriteLine("Відсортований масив");

for (int i = 0; i < a.Length; i++)

Console.Write(a[i]);

}

static void Main(string[] args)

{

int[] mas = { 5, 2, 4, 6, 1, 3 };

Console.WriteLine("Початковий масив");

for (int i = 0; i < mas.Length; i++)

Console.Write(mas[i]);

Console.WriteLine();

BubbleSort(mas);

Console.ReadKey();

}

}

}

Висновки: Час роботи елементарних алгоритмів сортування зростає квадратично O(n2) зі збільшенням розміру масиву тому їх доцільно застосовувати для невеликих масивів (колекцій).

Ефективні алгоритми сортування

4. Швидке сортування Хоара

Автор цього метода Ч. Хоар назвав його швидким сортуванням. Метод функціонує за принципом «розділяй та володарюй»: елементи масиву діляться на дві частини, і кожна з них потім сортується окремо. Для цього обирають деякий елемент x, назвемо його розділовим. Мета полягає у розташуванні всіх менших за х елементів зліва від х, а всіх більших за х елементів — справа від х. Поділивши масив, слід повторити процедуру сортування для кожної частини, потім - для частин цих частин і т. д., доки кожна з частин масиву не міститиме лише один елемент.

Отже, алгоритм методу Хоара є рекурсивним і для його реалізації зручно застосувати рекурсивну процедуру.

Швидке сортування (Хоара) є найширше вживаним і одним їх найефективніших алгоритмів.

Загальна схема алгоритму така:

  1. з масиву вибирається деякий опорний елемент а,

  2. запускається процедура розділення масиву, яка переміщає всі ключі, менші, або рівні а[i], ліворуч від нього, а всі ключі, більші, або рівні а[i] - вправо

  3. тепер масив складається з двох підмножин, причому ліва менша, або рівна правої,

  4. для обох підмасивів: якщо в підмасиві більше двох елементів, рекурсивно запускаємо для нього ту ж процедуру.

В кінці вийде повністю відсортована послідовність.

Розглянемо алгоритм детальніше.

На вході масив а[0]...a[N] і опорний елемент p, по якому буде робитися розділення.

  1. Введемо два покажчики: i та j. На початку алгоритму вони вказують, відповідно, на лівий і правий кінець послідовності.

  2. Рухатимемо покажчик i з кроком в 1 елемент у напрямку до кінця масиву, поки не буде знайдений елемент а[i] >= р. Потім аналогічним чином почнемо рухати покажчик j від кінця масиву до початку, поки не буде знайдений a[j] <= p.

  3. Далі, якщо i <= j, міняємо а[i] і а[j] місцями і продовжуємо рухати i,j по тих же правилах...

  4. Повторюємо крок 3, поки i <= j.

Розглянемо роботу процедури для масиву а[0]...a[6] і опорного елементу p = а[3].

Тепер масив роздільний на дві частини: всі елементи лівої менше або рівні p, всі елементи правої - більше, або дорівнюють р. Розділення завершене.

Псевдокод.

quickSort ( масив a, верхня границя N ) {

Вибрати опорний елемент p - середину масиву

Розділити масив по цьому елементу

Якщо підмасив зліва від p містить більше як один елемент,

викликати quickSort для нього.

Якщо підмасив праворуч від p містить більше як один елемент

викликати quickSort для нього.

}

Приклад 5. Реалізація швидкого сортування на мові C#

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace QuickSort

{

class QuickSorting

{

public static void sorting(double[] arr, long first, long last)

{

//Швидке сортування Хоара

double p = arr[(last - first) / 2 + first];

double temp;

long i = first, j = last;

while (i <= j)

{

while (arr[i] < p && i <= last) ++i;

while (arr[j] > p && j >= first) --j;

if (i <= j)

{

temp = arr[i];

arr[i] = arr[j];

arr[j] = temp;

++i; --j;

}

}

if (j > first) sorting(arr, first, j);

if (i < last) sorting(arr, i, last);

}

}

class Program

{

static void Main(string[] args)

{

double[] arr = new double[100];

Random rd = new Random();

for (int i = 0; i < arr.Length; ++i)

{

arr[i] = rd.Next(1, 101);

}

System.Console.WriteLine("Початковий масив:");

foreach (double x in arr)

{

Console.Write(x + " ");

}

Console.WriteLine();

//сортування

QuickSorting.sorting(arr, 0, arr.Length - 1);

System.Console.WriteLine("Відсортований масив:");

foreach (double x in arr)

{

System.Console.Write(x + " ");

}

Console.ReadKey();

}

}

}