简述
快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序,它采用了一种分治的策略。快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用。
快速排序的基本思想:通过一趟排序将待排数据分隔成独立的两部分,左边部分记录的数据要比中间值小,右边部分记录的数据要比中间值大,在得到中间值的基础上再对两部分数据分别继续进行排序,以达到整个序列有序。
代码
#include <QDebug>
#include <QCoreApplication>
void mDebug(int a[], int len)
{
QString str;
for (int i = 0; i < len; i++)
{
str += QString("%1 ").arg(a[i]);
}
qDebug() << str;
}
// l:left缩写, r:right缩写
void QuickSort(int a[], const int l, const int r)
{
// 当右索引小于或者等于左边索引时则不满足继续递归条件
if (r <= l) return;
// r2l: right -> left 表示从右到左开始是否成立
// 因为默认的中间值为左边首个元素,所以从右往左逐个递减比较
bool r2l = true;
int temp = a[l];
// 因为l、r都不可改,这里定义了中间变量记录左右数值,
// 因为找到中间索引后,还需根据中间索引再次调用递归,而递归的范围则是有l、r决定
int i = l, j = r;
while (i < j)
{
// 从右往左开始递减比较
if (r2l)
{
// 当右边索引所对应的数值小于等于中间值时
// 1.把右边索引对应的值赋值给左边索引对应的值
// 2.把左边索引+1
// 3.把r2l改为false,这回需要从左往右开始比较了
if (a[j] <= temp)
{
a[i] = a[j];
i++;
r2l = false;
}
// 如果右边索引所对应的值都比中间值大则继续往前一个再比较
else
{
j--;
r2l = true;
}
}
// 从左往右开始递增比较
else
{
// 当左边索引所对应的数值大于中间值时
// 1.把左边索引对应的值赋值给左右边索引对应的值
// 2.把右边索引-1
// 3.把r2l改为true,这回需要从右往左开始比较了
if (a[i] > temp)
{
a[j] = a[i];
j--;
r2l = true;
}
// 如果左边索引所对应的值都比中间值小则继续往后一个再比较
else
{
i++;
r2l = false;
}
}
}
// 把中间值填回去
a[i] = temp;
// 从中间值开始,分两部分比较
QuickSort(a, l, i-1);
QuickSort(a, i+1, r);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int s[] = {50, -1, 3, 4, 0, 5, 1000, 6, 7, 12, 8, 1, 2, 9, -530, 450, 77} ;
int len = sizeof(s)/sizeof(s[0]);
// 快速排序
QuickSort(s, 0, len - 1);
// 打印
mDebug(s, len);
return a.exec();
}
输出
"-530 -1 0 1 2 3 4 5 6 7 8 9 12 50 77 450 1000 "