[QuickSort]实现与测试(Implementation and test with C)
By EmilMatthew 05/9/4
Quicksort 是一个知名的排序算法,由计算机科学家: C. A. R. Hoare 开发,算法的平均效率在theta(n*log(n)):
参:
http://www.yotor.com/wiki/zh/qu/Quicksort.htm
这个算法的主要思想仍是分治(Conquer and Divide),就是先挑选一个数(通常是首项)然后把比这个数小的数字都放到它的左边,比它大(或等于)的数都放在它的右边。然后在左右的两个小区间里反复这样的一个过程,直至区间小到不能再区分为止(只有一个数),此时,数组的排序工作也完成了。
在qSort算法中,这个将数字分成左边小于它的数右边都是大于它的数的过程叫做pation.
先请看pation过程的flashPPT动态演示:
http://www.flash8.net/bbs/UploadFile/2005-9/20059413511870.swf
接下来是代码:long pation(Type* arr,long low,long high)
{
Type blankElement;
assertF(arr!=NULL,"in pation, arr is null/n");
blankElement=arr[low];
while(low<high)
{
while(arr[high]>=blankElement&&low<high)high--;
if(low<high)
{
arr[low]=arr[high];
low++;
}
while(arr[low]<=blankElement&&low<high)low++;
if(low<high)
{
arr[high]=arr[low];
high--;
}
}
assertF(high==low,"in quickSort's pation,high!=low/n");
arr[high]=blankElement;
return high;
}
Pation子过程的平均时间效率在theta(n)
Pation子过程的平均时间效率在theta(n)
Pation子过程的平均时间效率在theta(n)
Pation子过程的平均时间效率在theta(n)
剩下的就是qSort的主调用程序段,上面这个理解了之后,这个主程序就很好懂了:
void eQSort(Type* arr,long low,long high)
{
long mid;
assertF(arr!=NULL,"in qSort, arr is null/n");
if(high<=low)return;
else
{
mid=pation(arr,low,high);
eQSort(arr,low,mid-1);
eQSort(arr,mid+1,high);
}
}
其实,这里的首元素的选取是任意的,根本不用一定要以第一个元素为起点开始做,可以随机的选取一个位置作为主元,然后将第一个元素与之交换,不过这种算法期望运行时间仍在theta(n*log n).P.S.可能是由于我的随机数产生的方式(是在stdlib.h提供的rand函数的基础上做了一个产生的0-upLimit随机数算法)较慢,导致这个随机的快速排序算法的效率在测试中要比原来的慢些.
//这是我的随机数算法,现在看上去果然很低效啊,下次得自己写了~~~: )
Type eRandom(int upLimit)
{
Type tmpData;
do
{
tmpData=((Type)rand()/(Type)32767)*(Type)100.0*(Type)upLimit;
}
while(tmpData>upLimit);
return tmpData;
}
//这是随机的快速排序算法;
void eRQSort(Type* arr,long low,long high)
{
long rPos,mid;
assertF(arr!=NULL,"in qSort, arr is null/n");
if(high<=low)return;
else
{
rPos=low+(long)eRandom(high-low);
swapArrData(arr,low,rPos);
mid=pation(arr,low,high);
eRQSort(arr,low,mid-1);
eRQSort(arr,mid+1,high);
}
}
下面是我的测试结果:
a) 针对经典的QuickSort所做的测试:(编译器:VC6.0,语言:C)
b) 针对随机快速排序所做的测试(随机数生成算法效率过低).(编译器:VC6.0,语言:C)
| Quick Sort | ||
| 100,000个随机数 | 1,000,000个随机数 | 10,000,000个随机数 |
test1 | 0.047000s | 0.562000s | 10.344000s |
test2 | 0.047000s | 0.578000s | 10.860000s |
test3 | 0.047000s | 0.562000s | 10.282000s |
| Random Quick Sort | ||
| 100,000个随机数 | 1,000,000个随机数 | 10,000,000个随机数 |
test1 | 0.218000s | 2.578000s | 30.812000s |
test2 | 0.219000s | 2.562000s | 31.156000s |
test3 | 0.218000s | 2.594000s | 30.956000s |
而简单排序算法(bubble,selection,insert)在排序数目达到10,000的时候,算法的耗时就要以秒为单位来计算了。所以,当问题规模变大的时候,选择一种优秀的排序算法对最后的是否能在有效时间内得到结果显得至关重要。