Метод швидкого сортування.pptx
- Количество слайдов: 7
Швидке сортування (англ. Quick Sort) — алгоритм сортування, добре відомий, як алгоритм розроблений Чарльзом Хоаром, який не потребує додаткової пам'яті і виконує у середньому операцій. Однак, у найгіршому випадку робить порівнянь. Оскільки алгоритм використовує дуже прості цикли і операції, він працює швидше інших алгоритмів, що мають таку ж асимптотичну оцінку складності. Наприклад, зазвичай більш ніж удвічі швидший порівняно з сортуванням злиттям. Ідея алгоритму полягає в переставлянні елементів масиву таким чином, щоб його можна було розділити на дві частини і кожний елемент з першої частини був не більший за будьякий елемент з другої. Впорядкування кожної з частин відбувається рекурсивно. Алгоритм швидкого сортування може бути реалізований як у масиві, так і в двозв’язному списку.
* Переваги: * Один з самих швидкодіючих (на практиці) з алгоритмів внутрішнього сортування загального * * * * * призначення. Простий в реалізації. Вимагає лише додаткової пам'яті для своєї роботи. (Не покращений рекурсивний алгоритм в гіршому випадку пам'яті) Добре поєднується з механізмами кешування та віртуальною пам'яттю. Існує ефективна модифікація (алгоритм Седжвіка) для сортування рядків - спочатку порівняння з опорним елементом тільки по нульовому символу рядка, далі застосування аналогічної сортування для «більшого» і «меншого» масивів теж по нульовому символу, і для «рівного» масиву по вже першого символу. Працює на пов'язаних списках та інших структурах з послідовним доступом. Недоліки: Сильно деградує по швидкості при невдалих виборах опорних елементів, що може трапитися при невдалих вхідних даних. Цього можна уникнути, використовуючи такі модифікації алгоритму, як Introsort, або вибираючи опорний елемент випадково, а не фіксованим чином. Наївна реалізація алгоритму може привести до помилки переповнення стека, так як їй може знадобитися зробити вкладених рекурсивних викликів. У покращених реалізаціях, в яких рекурсивний виклик відбувається тільки для сортування меншою з двох частин масиву, глибина рекурсії гарантовано не перевищить. Нестійкий - якщо потрібна стійкість, доводиться розширювати ключ.
* * * * * * * * * * * function Quick. Sort(Array, Left, Right) var L 2, R 2, Pivot. Value begin Stack. Push(Left, Right); // pushes Left, and then Right, on to a stack while not Stack. Empty do begin Stack. Pop(Left, Right); // pops 2 values, storing them in Right and then Left repeat Pivot. Value : = Array[(Left + Right) div 2]; L 2 : = Left; R 2 : = Right; repeat while Array[L 2] < Pivot. Value do // scan left partition L 2 : = L 2 + 1; while Array[R 2] > Pivot. Value do // scan right partition R 2 : = R 2 - 1; if L 2 <= R 2 then begin if L 2 != R 2 then Swap(Array[L 2], Array[R 2]); // swaps the data at L 2 and R 2 L 2 : = L 2 + 1; R 2 : = R 2 - 1; end; until L 2 >= R 2; if R 2 - Left > Right - L 2 then // is left side piece larger? begin if Left < R 2 then Stack. Push(Left, R 2); Left : = L 2; end; else begin if L 2 < Right then // if left side isn't, right side is larger Stack. Push(L 2, Right); Right : = R 2; end; until Left >= Right; end;
* * * * * * * * program Quick_Sort; var A: array[1. . 100] of integer; N, i : integer; {У процедуру передаються ліва та права границі фрагменту, що сортується} procedure QSort(L, R: integer); var X, y, i, j: integer; begin X: =A[(L+R) div 2]; i: =L; j: =R; while i<=j do begin while A[i]
Очевидно, що функція partition працює за O(n). Спочатку вона раз викликається для всього масиву. Потім два рази для половинок ( O(n/2) + O(n/2) ). Потім чотири рази для четвертинок. А в самому кінці n разів для частин, розмір яких дорівнює 1. Тому бачимо що на кожному рівні рекурсії сумарний час роботи рівний O(n). Глибина ж рекурсії дорівнює ln(n), якщо масив ділиться на частини рівномірно. Складність алгоритму буде O(n ln(n) ) Якщо ж щоразу одна частина має один елемент, а інша всі решту, то таких поділів буде n. Тоді складність буде O(n 2).