Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторные работы PASCAL часть 1.doc
Скачиваний:
3
Добавлен:
23.08.2019
Размер:
1.04 Mб
Скачать

Сортування

Сортування вставками

Один із найпростіших способів відсортувати масив - сортування вставками. У повсякденному житті ми зштовхуємося з цим методом наприклад, при грі в карти. Щоб відсортувати наявні у вас карти, ви виймаєте карту, переміщуєте карти, що залишилися, а потім уставляєте карту на потрібне місце. Процес повторюється доти, поки хоч одна карта знаходиться не на місці. Як середній, так і гірший час для цього алгоритму - O(n2). Подальшу інформацію можна одержати в книжці [1].

На мал.1(a) ми виймаємо елемент 3. Потім елементи, розташовані вище, передвигаємо вниз - доти, поки не знайдемо місце, куди потрібно вставити 3. Це процес продовжується на рис.1 (b) для числа 1. Нарешті, на мал.1 (c) ми завершуємо сортування, помістивши 2 на потрібне місце.

Якщо довжина нашого масиву дорівнює n, нам потрібно пройтися по n-1 елементах. Щораз нам може знадобитися переміситти n-1 других елементів. От чому цей метод вимагає досить-таки багато часу.

Сортування вставками відноситься до числа методів сортування по місцю. Іншими словами, їй не потрібно допоміжна пам'ять, ми сортуємо елементи масиву, використовуючи тільки пам'ять, що займає сам масив. Крім того, вона є стійкою - якщо серед ключів, що сортуються є однакові, після сортування вони залишаються у вихідному порядку.

Сортування методом Шелла

Метод, запропонований Дональдом Л. Шеллом, є нестійким сортуванням по місцю. Ефективність методу Шелла пояснюється тим, що елементи які переміщуються, швидко потрапляють на потрібні місця. Середній час для сортування Шелла дорівнює O(n1.25), для гіршого випадку оцінкою є O(n1. 5). Подальші посилання див. у книжці [1].

На мал.1(a) був приведений приклад сортування вставками. Ми спочатку виймали 1, потім переміщували 3 і 5 на одну позицію вниз, після чого вставляли 1. Таким чином, нам були потрібні два переміщення. Наступного разу нам було потрібно два переміщення, щоб уставити на потрібне місце 2. На весь процес нам було потрібно 2+2+1=5 зрушень.

Рис.1. Сортування вставками

На мал.2(b) ілюструється сортування Шелла. Ми починаємо, виконуючи сортування вставками з кроком 2. Спочатку ми розглядаємо числа 3 і 1: витягаємо 2, переміщуємо 3 на 1 позицію з кроком 2, уставляємо 2. Потім повторюємо те ж для чисел 5 і 2: витягаємо 2, переміщуємо вниз 5, уставляємо 2. і т.д. Закінчивши сортування з кроком 2, робимо її з кроком 1, тобто виконуємо звичайне сортування вставками. Усього при цьому нам знадобиться 1 + 1+ 1 = 3 переміщення. Таким чином, використавши спочатку крок, більший 1, ми домоглися меншого числа переміщень.

Можна використовувати самі різні схеми вибору кроків. Як правило, спочатку ми сортуємо масив із великим кроком, потім зменшуємо крок і повторюємо сортування. У самому кінці сортуємо з кроком 1. Хоча цей метод легко пояснити, його формальний аналіз досить важкий. Зокрема, теоретикам не вдалося знайти оптимальну схему вибору кроків. Кнут [1] провів багато експериментів і отримав наступну формулу вибору кроків (h) для масиву довжини N:

У послідовності взяти якщо .

От декілька перших значень h:

, , ,

, .

Рис.2. Сортування методом Шелла

Щоб відсортувати масив довжиною 100, насамперед, знайдемо номер s, для котрого  100. Відповідно до наведених цифр, s = 5. Потрібне нам значення знаходиться двома рядками вище. Таким чином, послідовність кроків при сортуванні буде такою: 13-4-1. Звичайно, нам не потрібно берегти цю послідовність: чергове значення h знаходиться з попереднього за формулою: .

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

Хоча ідея Шелла значно поліпшує сортування вставками, резерви ще залишаються. Один із найбільше відомих алгоритмів сортування - швидке сортування, запропоноване Ч.Хоором. Метод і справді дуже швидкий, недарма по-англійському його так і величають QuickSort.

Цьому методу потрібно O(n lg n) у середнім і O(n2) у гіршому випадку. На щастя, якщо прийняти адекватні обережності, найгірший випадок украй малоймовірний. Швидкий пошук не є стійкою. Крім того, йому потрібно стек, тобто він не є і методом сортування на місці.

Алгоритм розбиває масив, що сортується на поділи, потім рекурсивно сортує кожний поділ.

На мал.3(a) у якості центрального обраний елемент 3. Індекси починають змінюватися з кінців масиву. Індекс i починається зліва і використовується для вибору елементів, що більше центрального, індекс j починається справа і використовується для вибору елементів, що менше центрального. Ці елементи змінюються місцями - див. мал.3(b). Процедура QuickSort рекурсивно сортує два підмасиви, у результаті утворюється масив, поданий на рис. 3(c).

Рис. 3: Приклад роботи алгоритму Quicksort

У процесі сортування може знадобитися пересунути центральний елемент. Якщо нам повезе, обраний елемент виявиться медіаною значень масиву, тобто розділить його навпіл. Припустимо, що це і справді так. Оскільки на кожному кроку ми ділимо масив навпіл, переглядаємо усі n елементів, час роботи алгоритму є O(n lg n).

У якості центрального можна попросту брати перший елемент (A[Lb]). Всі інші елементи масиву ми порівнюємо з центральним і пересуваємо або уліво від нього, або вправо. Є, однак, один випадок, що безжалісно руйнує цю прекрасну простоту. Припустимо, що наш масив із самого початку відсортований. Функція Partition завжди буде одержувати в якості центрального мінімальний елемент і тому розділить масив найгіршим способом: у лівому розділі виявиться один елемент, відповідно, у правому залишиться Ub - Lb елементів. Таким чином, кожен рекурсивний виклик процедури quicksort усього лише зменшить довжину масиву, що сортується на 1. У результаті для виконання сортування знадобиться n рекурсивних викликів, що приводить до часу роботи алгоритму порядку O(n2). Один із способів збороти цю проблему - випадково вибирати центральний елемент. Це зробить найгірший випадок надзвичайно малоймовірним.

Порівняння методів

У даному розділі ми порівняємо описані алгоритми сортування: вставками, Шелла і швидке сортування. Є декілька факторів, що впливають на вибір алгоритму в кожній конкретній ситуації:

  • Стійкість. Нагадаємо, що стійке сортування не змінює взаємного розташування елементів із рівними ключами. Сортування вставками - єдиний із розглянутих алгоритмів, що володіють цією властивістю.

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

  • Час. Таблиця 1 дозволяє порівняти тимчасові витрати кожного з алгоритмів по кількості що виконуються операторів.

Таблиця 1. Порівняння методів сортування

метод

statements

Середній час

Найгірший час

Сортування вставками

9

O(n2)

O(n2)

Сортування Шелла

17

O(n1. 25)

O(n1. 5)

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

21

O(n lg n)

O(n2)

  • Час, витрачений кожним з алгоритмів на сортування випадкового набору даних, подано в таблиці 2.

Таблиця 2. Час сортування

count

Сортування вставками

Сортування Шелла

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

16

39 s

45 s

51 s

256

4,969 s

1,230 s

911 s

4,096

1. 315 sec

.033 sec

.020 sec

65,536

416. 437 sec

1. 254 sec

.461 sec

Додаток 2