Быстрая сортировка — различия между версиями
| Строка 6: | Строка 6: | ||
* Разбиваем массив таким образом, что все элементы меньшие или равные опорному будут лежать левее опроного элемента, а большие или равные правее. | * Разбиваем массив таким образом, что все элементы меньшие или равные опорному будут лежать левее опроного элемента, а большие или равные правее. | ||
* Рекурсивно сотрируем "маленькие" и "большие" элементы. | * Рекурсивно сотрируем "маленькие" и "большие" элементы. | ||
| + | |||
| + | var | ||
| + | a : array [ 1 . .N] of integer ; | ||
| + | procedure QSort ( left , right : integer ) ; | ||
| + | var | ||
| + | i , j : integer ; | ||
| + | key : integer ; | ||
| + | buf : integer ; | ||
| + | begin | ||
| + | key := a [ random ( right - left + 1) + left ] ; | ||
| + | i := left ; | ||
| + | j := right ; | ||
| + | repeat | ||
| + | while a [ i ] < key do | ||
| + | inc ( i ) ; | ||
| + | while key < a [ j ] do | ||
| + | dec ( j ) ; | ||
| + | if i <= j then begin | ||
| + | buf := a [ i ] ; | ||
| + | a [ i ] := a [ j ] ; | ||
| + | a [ j ] := buf ; | ||
| + | inc ( i ) ; | ||
| + | dec ( j ) ; | ||
| + | end ; | ||
| + | unti l i > j ; | ||
| + | if l e f t < j then | ||
| + | QSort ( l e f t , j ) ; | ||
| + | if i < r i g h t then | ||
| + | QSort ( i , r i g h t ) ; | ||
| + | end ; | ||
| + | begin | ||
| + | . . . | ||
| + | QSort ( 1 , N) ; | ||
| + | end . | ||
===Оптимизация глубины рекурсии до O(logn) в худшем случае=== | ===Оптимизация глубины рекурсии до O(logn) в худшем случае=== | ||
Версия 18:55, 15 июня 2011
Быстрая сортировка(qsort, сортировка Хоара) - один из самых известных и широко используемых алгоритмов сортировки. В худшем случае работает за , среднее время работы , что является асимптотически оптимальным временем работы для алгоритма, основанного на сравнении.
Содержание
Алгоритм
- Выбираем опорный элемент.
- Разбиваем массив таким образом, что все элементы меньшие или равные опорному будут лежать левее опроного элемента, а большие или равные правее.
- Рекурсивно сотрируем "маленькие" и "большие" элементы.
var
a : array [ 1 . .N] of integer ;
procedure QSort ( left , right : integer ) ;
var
i , j : integer ;
key : integer ;
buf : integer ;
begin
key := a [ random ( right - left + 1) + left ] ;
i := left ;
j := right ;
repeat
while a [ i ] < key do
inc ( i ) ;
while key < a [ j ] do
dec ( j ) ;
if i <= j then begin
buf := a [ i ] ;
a [ i ] := a [ j ] ;
a [ j ] := buf ;
inc ( i ) ;
dec ( j ) ;
end ;
unti l i > j ;
if l e f t < j then
QSort ( l e f t , j ) ;
if i < r i g h t then
QSort ( i , r i g h t ) ;
end ;
begin
. . .
QSort ( 1 , N) ;
end .
Оптимизация глубины рекурсии до O(logn) в худшем случае
В случае повторяющихся неудачных разбиений опорным элементом, глубина рекурсии может достичь . Этого можно избежать, если в цикле разбивать массив, но рекурсивно вызываться только от части, содержащей меньшее число элементов, а большую часть продолжать разбивать в цикле.
Асимптотика
Oh, boy, here we go!
Худшее время работы
Обозначим худшее время работы за . Получим рекуррентное соотношение
Предположим, что . Тогда получим
Таким образом
Среднее время работы
Ссылки
http://ru.wikipedia.org/wiki/Быстрая_сортировка
http://en.wikipedia.org/wiki/Quicksort
Так как некий ленивый за***нец не собирается делать вики-конспект я его внаглую беру себе =^-^=.