Быстрая сортировка является одним из самых быстрых алгоритмов сортировки массивов. Скорость работы примерно равна O(n log n) операций при сортировке n элементов. Описание работы алгоритма:
— Из массива выбираем некоторый опорный элемент p;
— Делим массив на два подмассива, слева от p элементы меньшие либо равные p, а справа — большие либо равные p;
— Для каждого с подмассивов следует проделать ту же операцию, если в них более одного элемента.
#include <iostream>
#include <cstdlib> // для Visual C++ заменить на <ctime>
using namespace std;
const int SIZE = 25;
int array[SIZE];
// заполнение массива случайными числами
void GenerationArray()
{
// привязка ко времени для генерации чисел без повторений
srand(time(0));
for (int i=0; i<SIZE; i++)
{
// заполнение массива числами < 100
array[i] = rand()%100;
}
}
// вывод массива на экран
void ShowArray()
{
for (int i=0; i<SIZE; i++)
{
cout << array[i] << " ";
}
cout << endl;
}
// High и Low - верхняя и нижняя границы подмассива, который надо отсортировать
void QuickSort(long int High, long int Low)
{
long i, j; // для хранения границ подмассива
int p; // для хранения опорного элемента
int temp;
i = Low; // делаем копию нижней границы
j = High; // делаем копию верхней границы
p = array[(Low+High)/2]; // выбираем опорный элемент
// цикл будет работать, пока границы не пересекутся в массиве
do
{
// если элемент нижней границы меньше опорного элемента,
// передвигаем указатель i на один элемент вправо
while (array[i] < p) i++;
// если элемент верхней границы меньше опорного элемента,
// передвигаем указатель j на один элемент влево
while (array[j] > p) j--;
// если границы не пересеклись по позициям в массиве,
// меняем местами элементы i и j
if (i <= j)
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
} while (i <= j);
// если в выделенном подмассиве [Low, j] больше одного элемента,
// запускаем рекурсивно функцию QuickSort(long, long)
if (j > Low) QuickSort(j, Low);
// аналогично
if (High > i) QuickSort(High, i);
}
int main()
{
GenerationArray();
ShowArray();
QuickSort(SIZE-1, 0);
ShowArray();
return 0;
}
Сравнение скорости с сортировкой пузырьком и сортировкой выбором
В прошлой статье я сортировал 100 тысяч элементов сортировкой пузырьком (1 минута 38.731 секунд) и сортировкой выбором (28.313 секунд). Быстрая сортировка отсортировала столько же элементов за 0.024 секунды. Разница заметна :)
На сортировку 10 миллионов элементов ушло 2.333 секунды, в то время как на сортировку пузырьком 10 млн элементов ушло бы почти 23 месяца.
Если я правильно понял, то при вызове QuickSort в Low передается ноль.
Когда выбирается опорный эл-нт там идёт сложение Low (т.е. нуля) с High.
Для чего там идет сложение с нулём?
Что бы найти средний элемент в подмассиве, к примеру имеем массив с 10 чисел:
p = array[(0+9)/2]; // первый опорный элемент равен 4
То есть пятый элемент по счету. И далее будем делать то же самое с подмассивами, например в 5-ого элемента по 9-тый:
p = array[(5+9)/2]; // второй опорный элемент равен 7
Вот мы нашли следующий опорный элемент. Как видите у нас рекурсивная функция, которая параллельно сортирует левую и правую границы подмассивов:
// если в выделенном подмассиве [Low, j] больше одного элемента,
// запускаем рекурсивно функцию QuickSort(long, long)
if (j > Low) QuickSort(j, Low);
// аналогично
if (High > i) QuickSort(High, i);
Функция имеет общий вид, и нет смысла делать исключение только для первого вызова.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.
Когда выбирается опорный эл-нт там идёт сложение Low (т.е. нуля) с High.
Для чего там идет сложение с нулём?
То есть пятый элемент по счету. И далее будем делать то же самое с подмассивами, например в 5-ого элемента по 9-тый:
Вот мы нашли следующий опорный элемент. Как видите у нас рекурсивная функция, которая параллельно сортирует левую и правую границы подмассивов:
Функция имеет общий вид, и нет смысла делать исключение только для первого вызова.