快速排序是一种最坏情况复杂度为o(n^2),平均时间复杂度为o(nlgn)的排序算法,且nlgn隐含的常数因子非常小,最坏情况发生的概率也不高,进行的是原址排序,所以是采用度最高的一种排序算法,在c++的stdlib库中特别封装了qsort函数方便用户使用。
快速排序是冒泡排序的一种升级版本,主要思想就是选择数组中的一个值作为关键字(key),将数组中所有比key小的放在key前,比key大的放在key后,之后再对a[0,...key-1]和a[key+1,...end]递归地使用qsort过程,直到数组规模为1为止,这样就保证整个数组都是有序的了。
在实际过程中,一般选取数组最后一位作为key值,最初时将i的值选在数组外,之后遍历数组a[start,...,key-1],以i作为分界点,比key小的放在i左侧,大的放在i右侧,最后把a[key]与a[i]交换。
#include <stdio.h>
void qsort(int a[], int start, int end);
int divide(int a[], int start, int end);
int main()
{
int a[1000] = { 0 }, i = 0, n = 0, length = 0;
printf("请输入要排序的数组规模:");
scanf("%d", &n);
length = n;
while (n--)
scanf("%d", &a[i++]);
qsort(a, 0, length - 1);
i = 0;
while (length--)
printf("%d,", a[i++]);
return 0;
}
void qsort(int a[], int start, int end)
{
int key;
if (start < end)
{
key = divide(a, start, end);
qsort(a, start, key - 1);
qsort(a, key + 1, end);
}
}
int divide(int a[], int start, int end)
{
int key = 0, i = 0, j = 0,temp = 0;
key = a[end];
i = start - 1;
for (j = start; j < end; j++)
{
if (a[j] <= key)
{
i++;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
i++;
temp = a[i];
a[i] = a[end];
a[end] = temp;
return i;
}
要注意的是在交换值得时候不要写成下面这个样子,当i == j时会出现错误(变动的是同一个位置的数,最后就变成0了)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void qsort(int a[], int start, int end);
int divide(int a[], int start, int end);
int main()
{
int a[1000] = { 0 }, i = 0, n = 0, length = 0;
printf("请输入要排序的数组规模:");
scanf("%d", &n);
length = n;
while (n--)
scanf("%d", &a[i++]);
qsort(a, 0, length - 1);
i = 0;
while (length--)
printf("%d,", a[i++]);
return 0;
}
void qsort(int a[], int start, int end)
{
int key;
if (start < end)
{
key = divide(a, start, end);
qsort(a, start, key - 1);
qsort(a, key + 1, end);
}
}
int divide(int a[], int start, int end)
{
int key = 0, i = 0, j = 0, temp = 0, ran = 0;
srand((unsigned)time(NULL));
ran = start + rand() % (end - start); //注意范围
key = a[ran];
temp = a[end];
a[end] = a[ran];
a[ran] = temp;
i = start - 1;
for (j = start; j < end; j++)
{
if (a[j] <= key)
{
i++;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
i++;
temp = a[i];
a[i] = a[end];
a[end] = temp;
return i;
}
对于随机数法,还有一种更加细致地找到key值得方法——三数取中法,就是随机生成满足条件的三个数,之后取他们的中位数作为key值,这样选取对于样本来说更为“均衡”。void tail_qsort(int a[], int start, int end)
{
int q;
while (start < end)
{
q = divide(a, start, end);
tail_qsort(a, start, q - 1);
p = q + 1;
}
}