本快速排序经过改良,我们知道,快速排序通过主元分割数组,达到排序的目的。
如果数据量很大,需要使用很多次递归。前期当数组很大的时候很划算,但是经过分割多次后的数组很小,再使用递归就不礼貌了,不如设定一个cutoff的变量,当分割后的数组的数据量小于这个cutoff时,对此数组使用非递归排序,就可以节约时间和空间。
这里我使用的是插入排序。
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int number = 100000;//待排序数组的长度
int cutoff = 100;//此值越大,越早跳出递归使用插入排序。
int randNum = 10000;//设定随机值的范围
/*将指针指向的值交换*/
void swap(int *p,int *q)
{
int temp = *p;
*p = *q;
*q = temp;
}
/*插入排序*/
void insertionSort(int *a,int num)
{
//从第二个元素开始,与前面已经排序好的元素进行比较,
for(int i = 1;i < num;i++)
{
//选择位置为i的数据与前面的数据进行比较,从第2个元素开始比较,*(a+i)
for(int j = i;j > 0;j--)
{
//10,9,8,7,6,5,4,3,2,1
//将*(a+j-1)与*(a+j)逐个进行比较,遇到*(a+j-1)大于*(a+j)的,立即将两个数进行交换。
if( *(a+j-1) > *(a+j))
{
swap(a+j-1,a+j);
}
}
}
}
/*获取主元*/
int getPivot(int a[],int left,int right)
{
int center = (left + right) / 2;
if(a[left] > a[center])
{
swap(&a[left],&a[center]);
}
if(a[left] > a[right])
{
swap(&a[left],&a[right]);
}
if(a[center] > a[right])
{
swap(&a[center],&a[right]);
}
swap(&a[center],&a[right-1]);//将pivot藏在右边。
return a[right-1];
}
/*快速排序*/
void quickSort(int a[],int left,int right)
{
int pivot;
int i,j;
if(cutoff <= right - left)
{
//选取主元
pivot = getPivot(a,left,right);
i = left;
j = right-1;
while(1)
{
while(a[++i] < pivot);
while(a[--j] > pivot);
if(i < j)
{
swap(&a[i],&a[j]);
}
else break;
}
swap(&a[i],&a[right-1]);
quickSort(a,left,i-1);
quickSort(a,i+1,right);
}
else
{
insertionSort(a+left,right-left+1);
}
}
/*快速排序接口*/
void quickSortShell(int a[],int num)
{
quickSort(a,0,num-1);
}
int main(void)
{
srand((unsigned)time( NULL ) );
int a[number];
for(int i = 0;i < number;i++)
{
a[i] = rand()%randNum;
}
quickSortShell(a,number);
for(int j = 0;j < number;j++)
{
printf("%d,",a[j]);
}
return 0;
}