Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Алгоритмы сортировки данных.doc
Скачиваний:
1
Добавлен:
29.06.2024
Размер:
429.57 Кб
Скачать

1.1.1.6.2Алгоритм

Быстрая сортировка использует стратегию «разделяй и властвуй». Шаги алгоритма таковы:

1. Выбираем в массиве некоторый элемент, который будем называть опорным элементом. С точки зрения корректности алгоритма выбор опорного элемента безразличен. С точки зрения повышения эффективности алгоритма выбираться должна медиана, но без дополнительных сведений о сортируемых данных её обычно невозможно получить. Известные стратегии: выбирать постоянно один и тот же элемент, например, средний или последний по положению; выбирать элемент со случайно выбранным индексом.

2. Операция разделения массива: реорганизуем массив таким образом, чтобы все элементы, меньшие или равные опорному элементу, оказались слева от него, а все элементы, большие опорного — справа от него.

Существует два варианта разделения списка:

Вариант 1.

Функция PivotList берет в качестве осевого элемента первый элемент списка и устанавливает указатель pivot в начало списка. Затем она проходит по списку, сравнивая осевой элемент с остальными элементами списка. Обнаружив элемент, меньший осевого, она увеличивает указатель PivotPoint, а затем переставляет элемент с новым номером PivotPoint и вновь найденный элемент. После того, как сравнение части списка с осевым элементом уже произведено, список оказывается разбит на четыре части. Первая часть состоит из первого осевого — элемента списка. Вторая часть начинается с положения f irst+1, кончается в положении PivotPoint и состоит из всех просмотренных элементов, оказавшихся меньше осевого. Третья часть начинается в положении PivotPoint+1 и заканчивается указателем параметра цикла index. Оставшаяся часть списка состоит из еще не просмотренных значений.

Алгоритм.

PivotListdist , first .last)

list обрабатываемый список

first номер первого элемента

last номер последнего элемента

PivotValue=list [first]

PivotPoint=first

for index=f irst+1 to last do

if list [index] <Pivot Value then

PivotPoint=PivotPoint+l

Swap(list [PivotPoint] , list [index] )

end if

end for

// перенос осевого значения на нужное место

Swap (list [first], list [PivotPoint])

return PivotPoint

Рис. 4.1. Пример разбиения элементов списка на четыре группы

Вариант 2.

Второй вариант алгоритма разбиения списка предусматривает наличие двух указателей в списке. Первый идет снизу, второй - сверху. В основном цикле алгоритма нижний указатель увеличивается до тех пор, пока не будет обнаружен элемент, больший PivotValue, а верхний уменьшается пока не будет обнаружен элемент, меньший PivotValue. Затем найденные элементы меняются местами. Этот процесс повторяется пока два указателя не перекроются. Эти внутренние циклы работают очень быстро, поскольку исключаются накладные расходы на проверку конца списка; проблема, однако, состоит в том, что при перекрещивании они

делают лишний обмен. Поэтому алгоритм следует подкорректировать, добавив в него еще один обмен

Вариант 2.

PivotList(list.first,last)

list обрабатываемый список элементов

first номер первого элемента

last номер последнего элемента

PivotValue=list[first]

lower=first

upper=last+l

do

do upper=upper-l until list[upper]<=PivotValue

do lower=lower+l until list[lower]>=PivotValue

Swap(list[upper],list[lower])

until lower>=upper

// устранение лишнего обмена

Swap(list[upper].list [lower])

// перенос оси в нужное место

Swap(list[first],list[upper])

return upper

3. Рекурсивно упорядочиваем подмассивы, лежащие слева и справа от опорного элемента.

4. Базой рекурсии являются наборы, состоящие из одного или двух элементов. Первый возвращается в исходном виде, во втором, при необходимости, сортировка сводится к перестановке двух элементов. Все такие отрезки уже упорядочены в процессе разделения.

Поскольку в каждой итерации (на каждом следующем уровне рекурсии) длина обрабатываемого отрезка массива уменьшается, по меньшей мере, на единицу, терминальная ветвь рекурсии будет достигнута всегда и обработка гарантированно завершится.