Швидке сортування
| Швидке сортування | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
Алгоритм у дії під час сортування списку чисел. |
||||||||||
| Основні відомості | ||||||||||
|
Швидке сортування (англ. Quick Sort) — алгоритм сортування, добре відомий, як алгоритм розроблений Чарльзом Хоаром, який не потребує додаткової пам'яті і виконує у середньому
операцій. Однак, у найгіршому випадку робить O(n2) порівнянь. Оскільки алгоритм використовує дуже прості цикли і операції, він працює швидше інших алгоритмів, що мають таку ж асимптотичну оцінку складності.
Ідея алгоритму полягає в переставлянні елементів масиву таким чином, щоб його можна було розділити на дві частини і кожний елемент з першої частини був не більший за будь-який елемент з другої. Впорядкування кожної з частин відбувається рекурсивно. Алгоритм швидкого сортування може бути реалізований як у масиві, так і в двозв’язному списку.
Швидке сортування є алгоритмом на основі порівнянь, і не є стабільним.
Зміст |
[ред.] Історія
Алгоритм швидкого сортування було розроблено Чарльзом Хоаром (C. A. R. Hoare) у 1962 під час роботи у маленькій британській компанії Elliott Brothers.[1]
[ред.] Псевдокод алгоритму
[ред.] Класичний алгоритм
В класичному варіанті, запропонованому Хоаром, з масиву обирався один елемент, і весь масив розбивався на дві частини по принципу: в першій частині — ті що не більші даного елементу, в другій частині — ті що не менші даного елемента. Процедура Quicksort(A,p,q) здійснює часткове впорядкування масиву
з p-го по q-ий індекс:
1 if
return; 2
3
4
5 while
do 6 repeat 7
8 until
9 repeat 10
11 until
12 if
13 then Поміняти
14
15
![]()
[ред.] Сучасний алгоритм
На сьогодні в стандартних бібліотеках використовують таку реалізацію алгоритму:
1
2
3 for
to
4 do if
5 then
6 Поміняти
7
8 Поміняти
9 return
![]()
1 if
return; 2
3
4
![]()
[ред.] Аналіз
Час роботи алгоритму сортування залежить від збалансованості, що характеризує розбиття. Збалансованість, у свою чергу залежить від того, який елемент обрано як опорний (відносно якого елемента виконується розбиття). Якщо розбиття збалансоване, то асимптотично алгоритм працює так само швидко як і алгоритм сортування злиттям. У найгіршому випадку, асимптотична поведінка алгоритму настільки ж погана, як і в алгоритму сортування включенням.
[ред.] Найгірше розбиття
Найгірша поведінка має місце у тому випадку, коли процедура, що виконує розбиття, породжує одну підзадачу з n-1 елементом, а другу — з 0 елементами. Нехай таке незбалансоване розбиття виникає при кожному рекурсивному виклику. Для самого розбиття потрібен час
. Тоді, рекурентне співвідношення для часу роботи, можна записати так:

Розв'язком такого співвідношення є
.
[ред.] Найкраще розбиття
В найкращому випадку процедура Partition ділить задачу на дві підзадачі, розмір кожної не перевищує n/2. Час роботи, описується нерівністю:

Тоді:
— асимптотично найкращий час.
[ред.] Середній випадок
Математичне очікування часу роботи алгоритму на всіх можливих вхідних масивах є
, тобто середній випадок ближчий до найкращого.
[ред.] Модифікації
В середньому алгоритм працює дуже швидко, але на практиці, не всі можливі вхідні масиви мають однакову імовірність. Тоді, шляхом додання рандомізації вдається отримати середній час роботи в будь-якому випадку.
[ред.] Рандомізованний алгоритм
В рандомізованному алгоритмі, при кожному розбитті випадковий елемент обирається в якості опорного:
1
2 Поміняти
9 return
![]()
1 if
return; 2
3
4
![]()
[ред.] Реалізації на різних мовах програмування
[ред.] Псевдокод, нерекурсивний алгоритм
function QuickSort(Array, Left, Right)
var
L2, R2, PivotValue
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
PivotValue := Array[(Left + Right) div 2];
L2 := Left;
R2 := Right;
repeat
while Array[L2] < PivotValue do // scan left partition
L2 := L2 + 1;
while Array[R2] > PivotValue do // scan right partition
R2 := R2 - 1;
if L2 <= R2 then
begin
if L2 != R2 then
Swap(Array[L2], Array[R2]); // swaps the data at L2 and R2
L2 := L2 + 1;
R2 := R2 - 1;
end;
until L2 >= R2;
if R2 - Left > Right - L2 then // is left side piece larger?
begin
if Left < R2 then
Stack.Push(Left, R2);
Left := L2;
end;
else
begin
if L2 < Right then // if left side isn't, right side is larger
Stack.Push(L2, Right);
Right := R2;
end;
until Left >= Right;
end;
end;
[ред.] Программа на Pascal
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]<X do i:=i+1;
while A[j]>X do j:=j-1;
if i<=j then
begin
y:=A[i]; A[i]:=A[j]; A[j]:=y;
i:=i+1; j:=j-1;
end;
end;
if L<j then QSort(L,j);
if i<R then QSort(i,R);
end;
begin
write('Кількисть елементів масиву ');
read(N);
for i:=1 to n do read(A[i]);
QSort(1,n); {Впорядкувати елементи з першого по n-ний}
for i:=1 to n do write(A[i],' '); {Упорядкований масив}
end.
[ред.] Примітки
- ↑ «Timeline of Computer History: 1960». Computer History Museum. http://www.computerhistory.org/timeline/?year=1960.
[ред.] Джерела інформації
- Thimas H. Cormen; Charles E. Leiserson; Ronald L. Rivest; Clifford Stein. Introduction to Algorithms (2nd ed.) The MIT Press. ISBN 0-07-013151-1
[ред.] Див. також
[ред.] Посилання
- Animated Sorting Algorithms: Quick Sort – графічна демонстрація роботи алгоритму
- Animated Sorting Algorithms: 3-Way Partition Quick Sort – графічна демонстрація алгоритму швидкого сортування з розбиттям масиву на три частини
- Interactive Tutorial for Quicksort
- Analyze Quicksort in an online Javascript IDE
- Javascript Quicksort and Bubblesort
- Quicksort applet
- Multidimensional quicksort in Java
- Literate implementations of Quicksort in various languages
- Quicksort tutorial with illustrated examples
- A colored graphical Java applet
|
||||||||||||||||||||||||||||

1 if
return;
2
3
4
5 while
do
6 repeat
7
8 until
9 repeat
10
11 until
12 if
14
15
1
2
to
4 do if
5 then
9 return
1 if
3
4
1
2 Поміняти
9 return
1 if
3
4