
- •Курсовая работа
- •Операторы управления
- •Структуры и объединения
- •Д. Кнут "Искусство программирования для эвм " том 3 "Сортировка и поиск" пузырьковая сортировка
- •Сортировка вставками
- •Сортировка шелла
- •Быстрая сортировка
- •Хеширование
- •Определение хэша и его вычисление
- •Пример задачи. Поиск одинаковых строк
- •Хэш подстроки и его быстрое вычисление
- •Применение хэширования
- •Определение количества различных подстрок
Быстрая сортировка
Быстрая сортировка, придуманная Ч. А. Р. Хоаром (Charles Antony Richard Hoare) и названная его именем, является самым лучшим методом сортировки из представленных в данной книге и обычно считается лучшим из существующих в настоящее время алгоритмом сортировки общего назначения. В ее основе лежит сортировка обменами — удивительный факт, учитывая ужасную производительность пузырьковой сортировки!
Быстрая сортировка построена на идее деления. Общая процедура заключается в том, чтобы выбрать некоторое значение, называемое компарандом(comparand), а затем разбить массив на две части. Все элементы, большие или равные компаранду, перемещаются на одну сторону, а меньшие — на другую. Потом этот процесс повторяется для каждой части до тех пор, пока массив не будет отсортирован. Например, если исходный массив состоит из символовfedacb, а в качестве компаранда используется символd, первый проход быстрой сортировки переупорядочит массив следующим образом:
Начало f e d a c b
Проход 1 b c a d e f
Затем сортировка повторяется для обеих половин массива, то есть bсаиdef. Как вы видите, этот процесс по своей сути рекурсивный, и, действительно, в чистом виде быстрая сортировка реализуется как рекурсивная функция.
Значение компаранда можно выбирать двумя способами — случайным образом либо усреднив небольшое количество значений из массива. Для оптимальной сортировки необходимо выбирать значение, которое расположено точно в середине диапазона всех значений. Однако для большинства наборов данных это сделать непросто. В худшем случае выбранное значение оказывается одним из крайних. Тем не менее, даже в этом случае быстрая сортировка работает правильно. В приведенной ниже версии быстрой сортировки в качестве компаранда выбирается средний элемент массива.
/* Функция, фызывающая функцию быстрой сортировки. */
void quick(char *items, int count)
{
qs(items, 0, count-1);
}
/* Быстрая сортировка. */
void qs(char *items, int left, int right)
{
register int i, j;
char x, y;
i = left; j = right;
x = items[(left+right)/2]; /* выбор компаранда */
do {
while((items[i] < x) && (i < right)) i++;
while((x < items[j]) && (j > left)) j--;
if(i <= j) {
y = items[i];
items[i] = items[j];
items[j] = y;
i++; j--;
}
} while(i <= j);
if(left < j) qs(items, left, j);
if(i < right) qs(items, i, right);
}
В этой версии функция quick()готовит вызов главной сортирующей функцииqs(). Это обеспечивает общий интерфейс с параметрамиitemsиcount, но несущественно, так как можно вызывать непосредственно функциюqs()с тремя аргументами.
Получение количества сравнений и обменов, которые выполняются при быстрой сортировке, требует математических выкладок, которые выходят за рамки данной книги. Тем не менее, среднее количество сравнений равно
nlogn
а среднее количество обменов примерно равно
n/6 logn
Эти величины намного меньше соответствующих характеристик рассмотренных ранее алгоритмов сортировки.
Необходимо упомянуть об одном особенно проблематичном аспекте быстрой сортировки. Если значение компаранда в каждом делении равно наибольшему значению, быстрая сортировка становится "медленной сортировкой" со временем выполнения порядка n2. Поэтому внимательно выбирайте метод определения компаранда. Этот метод часто определяется природой сортируемых данных. Например, в очень больших списках почтовой рассылки, в которых сортировка происходит по почтовому индексу, выбор прост, потому что почтовые индексы довольно равномерно распределены — компаранд можно определить с помощью простой алгебраической функции. Однако в других базах данных зачастую лучшим выбором является случайное значение. Популярный и довольно эффективный метод — выбрать три элемента из сортируемой части массива и взять в качестве компаранда значение, расположенное между двумя другими.