关于快速排序的基本算法见博客快速排序
3、快速排序的四种优化方案
(1)优化选取枢纽
在前面的方法中我们选取第一个元素作为枢纽,50刚好是中间数,但是若第一个数不是中间数,而是最大数或最小数怎么解决。
所以key=arr[low]变成了一个潜在的性能瓶颈。
改进办法1:获取数组元素的随机数作为枢纽,但是随机数可能不是中间数。而且随机数生成器本身还会带来时间上的开销,因此随机数生成不予考虑。
改进办法2:三数取中。在最左端、最右端和中间三个数中选取中数作为key值,这样key值位于较为中间的值的可能性就大大提高。
在排序方法的int key = arr[low];添加如下代码:
//排序方法
private static int sort(int[] arr, int low, int high) {
//计算数组中间的元素的下标
int mid=low+(high-low)/2;
//交换左端与右端的数据,保证左端较小
if(arr[low]>arr[high]){
swap(arr,low,high);
}
//交换中间与右端的数据,保证中间较小
if(arr[mid]>arr[high]){
swap(arr,mid,high);
}
//交换中间与左端的数据,保证左端是中数
if(arr[mid]>arr[low]){
swap(arr,mid,low);
}
//用优化后的第一个记录作枢纽
int key = arr[low];
while (low < high) {
//......
}
return low;
}
三数取中对小数组来说有很大的概率选择到一个比较好的key,但是对于非常大的待排序的序列来说还是不足以保证能够选择出一个好的key,因此还有个办法就是“九数取中”,它先从数组中分三次取样,每次取三个数,三个样品各取出中数,然后从这三个中数当中再取出一个中数作为枢纽。这样更加保证了取到的key是比较接近中间值关键字。