快速排序算法的实现并不难,算法平均意义上的时间复杂度是nlgn,最差意义上的时间复杂度是n*n(待排序序列基本有序的情况下效果最差),算法的好坏取决于所选取的用于划分数组的元素的大小。算法的思路是:将数组按照某个元素划分为两个部分,并单独对这两个部分数组进行就地排序,就地排序时重复利用划分的方法将数组分为更小的两部分。
下面的代码在一般的快速排序的算法实现的基础上改进 将每次基准元素随机在区间选出一个元素,而不是默认选择区间第一个元素
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int selectRandom(int *a,int n);
int pivotLoc(int *arr,int s,int e);
void quicksort(int *arr,int s,int e);
int main()
{
int i;
int a[] = {48,6,57,42,60,72,83,73,88,85};
quicksort(a,0,9);
for(i=0;i < 10;i++)
printf("%d ",a[i]);
prinitf("\n");
}
int pivotLoc(int *arr,int l,int r)
{
srand((unsigned)time(0));//
int x,i,j,tmp;
x = rand()%(r-l+1)+l;
tmp = arr[l];
arr[l] = arr[x];
arr[x] = tmp; //进行随机化处理 使第一个元素为这个区间随机取的一个数 下面会详细解释其原理
x = arr[l];
i =l,j = r;
while(i<j)
{
while( i < j && arr[j] >= x)
j--;
if(i < j)
arr[i++] = arr[j];
while( i < j && arr[i] <=x )
i++;
if(i < j)
arr[j--] = arr[i];
}
arr[i] = x;
return i;
}
void quicksort(int *arr,int l,int r)
{
int tmp;
if(l<r)
{
tmp = pivotLoc(arr,l,r);
quicksort(arr,l,tmp-1);
quicksort(arr,tmp+1,r);
}
}
函数srand和rand()配合使用产生伪随机数序列。rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。srand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列
如何产生设定范围内的随机数:
由于rand产生的随机数从0到rand_max,而rand_max是一个很大的数,那么如何产生从X~Y的数呢?
从X到Y,有Y-X+1个数,所以要产生从X到Y的数,只需要这样写:
k=rand()%(Y-X+1)+X;
这样,就可以产生你想要的任何范围内的随机数了