опорным элементом

advertisement
Цель
Упорядочить значения массива по возрастанию.
Алгоритм
Быстрая сортировка использует стратегию «разделяй и властвуй». Шаги
алгоритма таковы:
1. Выбираем в массиве некоторый элемент, который будем
называть опорным элементом. С точки зрения корректности алгоритма
выбор опорного элемента безразличен.
2. Операция разделения массива: реорганизуем массив таким образом,
чтобы все элементы со значением меньшим или равным опорному
элементу, оказались слева от него, а все элементы, превышающие по
значению опорный — справа от него. Обычный алгоритм операции:
1. Два индекса — l и r, приравниваются к минимальному и
максимальному индексу разделяемого массива, соответственно.
2. Вычисляется индекс опорного элемента m.
3. Индекс l последовательно увеличивается до тех пор, пока l-й
элемент не окажется больше либо равен опорному.
4. Индекс r последовательно уменьшается до тех пор, пока r-й
элемент не окажется меньше либо равен опорному.
5. Если r = l — найдена середина массива — операция разделения
закончена, оба индекса указывают на опорный элемент.
6. Если l < r — найденную пару элементов нужно обменять местами
и продолжить операцию разделения с тех значений l и r, которые
были достигнуты. Следует учесть, что если какая-либо граница
(l или r) дошла до опорного элемента, то при обмене значение m
изменяется на r-й или l-й элемент соответственно, изменяется
именно индекс опорного элемента и алгоритм продолжает свое
выполнение.
3. Рекурсивно упорядочиваем подмассивы, лежащие слева и справа от
опорного элемента.
4. Базой рекурсии являются наборы, состоящие из одного или двух
элементов. Первый возвращается в исходном виде, во втором, при
необходимости, сортировка сводится к перестановке двух элементов.
Все такие отрезки уже упорядочены в процессе разделения.
Тестовый пример
Исходный массив:
2 4 5 1 56 87 32 3 5 23 78 4 2
Упорядоченный массив:
1 2 2 3 4 4 5 5 23 32 56 78 87
Блок-схема
Код
// quckSort.cpp : аогоритм быстрой сортировки
#include "stdafx.h"
const int N=7;
// количество элементов
int a[]={1,3,2,6,4,5,2}; // рабочий массив
/*! Пересталяет значения аргументов местами
*
param n1 первый аргумент
*
param n2 второй аргумент
*/
void swap(int&n1, int& n2)
{
int tmp=n1;
n1=n2;
n2=tmp;
}
/*! Сортирует массив целых чисел используя алгоритм быстрой сортировки
*
param s_arr массив целых чисел
*
param first индекс элемента, с которого начинается сортировка
*
param last
индекс элемента, которым заканчивается сортировка
*/
void qs(int* s_arr, int first, int last)
{
int i = first;
// начальный индекс
int j = last; // конечный индекс
int x = s_arr[(first + last) / 2];
// значение элемента посередине между
индексами first и last
do {
// ищем индекс элемента с начала, у которого значение не меньше, чем у x
while (s_arr[i] < x) i++;
// ищем индекс элемента с конца, у которого значение не больше, чем у x
while (s_arr[j] > x) j--;
if(i <= j) {// индекс с начала не превышает индекс с конца
// если индекс найденный сначала меньше индекса найденного с конца
if (i < j) swap(s_arr[i], s_arr[j]);
// переставить элементы с
данными индексами местами
i++;
// увеличиваем начальный индекс на 1
j--;
// уменьшаяем конечный индекс на 1
}
// повторить цикл, если начальный индекс не превышает конечный
} while (i <= j);
if (i < last) //
qs(s_arr,
if (first < j)//
qs(s_arr,
если начальный индекс меньше последнего
i, last); // отсортировать рекурсивно элементы от i до last
если первый индекс меньше конечного
first,j); // отсортировать рекурсивно элементы от first до j
}
/*! печать целочисленного массива
* param array массив
* param size размер массива
*/
void printArray(int* array, int size)
{
for (int i=0;i<size;++i)
{
printf("%d ",array[i]);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
printArray(a,N); // массив до сортировки
puts("");
qs(a,0,N);
// сортировка
printArray(a,N);// массив после сортировки
return 0;
}
Download