引用严蔚敏的《数据结构》的话,在所有数量级都为nlgn的排序方法中,快排的常数因子k最小。这意味着快排是目前被认为是最好的一种内部排序方法。
下面先放出快排的代码:
void QuickSort(int *a,int low,int high){
if(low<high){
int l = low,h = high,flag = a[low];
while(l<h){
while(l<h&&a[h]>=flag) h--;
a[l] = a[h];
while(l<h&&a[l]<=flag) l++;
a[h] = a[l];
}
a[l] = flag;
QuickSort(a,low,l-1);
QuickSort(a,l+1,high);
}
}
所以分析快排的时间性能就很有必要了。影响快排的重要因素是枢轴数的选择。理想情况下,如果每次划分两个子数组的长度都相同,那么效率肯定会是最高的,那如果我们每次都找到数组中的中位数作为枢轴数那就可以了。然而输入的数组本身肯定是无序的,如果要找到中位数就需要有序输入,这个做法肯定不行的,我们对快排的改进必须建立在保证递归里的一次操作时间复杂度为O(n)。
教科书上给出的方法是选择数组第一个数为枢轴数。
优化一:随机选择枢轴数
当数组部分有序,选择第一个数为枢轴数,快排的比较次数会大幅度增加,而且划分子数组的长度会差异较大,当数组基本有序,快排就蜕变为冒泡了,如果随机选择枢轴数,就可以利用随机性来规避这种情况,下面我们来修改一下代码为:
//要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a;
void QuickSort_random(int *a,int low,int high){
if(low<high){
int random = (