一、思想
将数组的第一个数设置为关键字,通过一趟排序将待排记录分割成独立的两部分,其中,第一部分的关键字均比第二部分的关键字小,即第一部分小于等于关键字,第二部分大于关键字,分别对这两部分继续排序,直到整个序列有序。
图解如下:
二、代码
public class KuaiSort1 {
public static void swap(int []arr,int low,int high){
int temp = arr[low];
arr[low] = arr[high];
arr[high] = temp;
}
/**
* 得到其他数大小的衡量标准
* @param arr
* @param low
* @param high
* @return
* @return
*/
public static int getMiddle(int [] arr,int low,int high) {
int first = low;
int temp = arr[low];
while(low < high) {
while(low<high && arr[high]>=temp) {//必须high先走,low再走
high--;
}
/*if(low < high) {
swap(arr,low,high);
}*/
while(low<high && arr[low]<=temp) {
low++;
}
if(low<high){
swap(arr,low,high);
}
}
//将基准数归位
arr[first] = arr[high];
arr[high] = temp;
return high;
}
/**
* 递归形式的分治排序算法
* @param arr
* @param low
* @param high
*/
public static void quickSort(int [] arr,int low,int high) {
if(low < high) {
int middle = getMiddle(arr,low,high);//找到关键字所在的位置,分别对其前后两部分进行排序
quickSort(arr,0,middle-1);
quickSort(arr,middle+1,high);
}
}
public static void main(String [] args) {
int [] arr = {4,2,6,9,8,6,3,11,20,7};
KuaiSort1.quickSort(arr,0,arr.length-1);
for(int c:arr) {
System.out.print(c+" ");
}
}
}
三、快速算法的时间复杂度
一般情况及最好情况:O(nlgn)
最坏情况:O(n2)
四:改进
(1)和插入排序相结合
由于快速排序在处理小规模数据时表现不好,因此在数据规模小到一定程度时,改用插入排序,具体小到何种程度,一般文章说5-10.
(2)中轴元素(左边比它小,右边比它大),可以选最左边,最右边、中间这三个位置的的中值(中位数)。
(3)在分区的时候将序列分为3堆,一堆小于中轴元素,一堆等于中轴元素,一堆大于中轴元素,下次递归调用快速排序的时候,只需对大于和小于中轴元素的两堆数据进行排序,中间等于中轴元素的一堆已放好,降低了子问题的规模。