在聊快速排序之前,我们先解释一下荷兰国旗,即把一个数组分成三个部分,我们一般选最后一个元素作为基准值,即大于这个数的全部在左边,小于这个数的全部在右边,等于的在中间。
举个例子:arr{1,5,3,7,4,2,3,4},选取4做基准值,把他排成{1,3,2,3,4,4,7,5}大于小于区域的数顺序不要求。
荷兰国旗算法描述
首先第一步设less指针为-1,more指针为length-1。你可以想象成less是一个小于区域的右边界而more是大于区域的左边界。
然后把left指针所指的数和right指针所指的数进行比较。
如果arr[left]>arr[right],即比目标数大那么,arr[left]与less指针的下一个数交换,left+1。
如果arr[left]>arr[right],即比目标数大那么,arr[left]与more指针的前一个数交换,left不变,more-1。
直到最后left指针与more指针相遇,不能相等。比较结束,最后一步把一直没挪窝的基准值arr[right]放到arr[more](左边数第一个比基准值大的数)的位置上。
结束。
荷兰国旗代码展示
static public int[] partion(int[] arr,int left,int right){
int less = left-1;//小于区域右边界
int more = right;//大于区域左边界
//arr[right]是划分值
while (left<more){//当前指针不可以超过more区域,因为里面的数字已经排好序了
if (arr[left]<arr[right]){
//小于标准值 当前值与小于区域右边第一个数交换 小于区域扩大1 left++
ArrayUtils.swap(arr,++less,left++);
}if (arr[left]>arr[right]){
//大于标准值
ArrayUtils.swap(arr,--more,left);
}else {
//等于标准值
left++;
}
}
//因为由始至终标准值arr[right]都没有移动过
// 所以现在就剩最后一步把right移动到大于区域左边界左侧的位置即等于区域的右边界
ArrayUtils.swap(arr,more,right);
return new int[]{less++,more};
}
快排算法描述
有了前面荷兰国旗的基础,快排就是在荷兰国旗的基础上递归。先把一个数字用荷兰国旗的方法整理一遍,然后大于区域再做一次荷兰国旗,右边再做,一直做到数组只剩一个数,递归停止。
然而这样排序还是有一个缺陷就是如果最右侧的数字很小,两侧的数字不均匀会导致算法时间复杂度变差,针对这个问题我们可以随机选择一个数字来作为基准值,这样好和差的情况都会变成概率问题,算法时间复杂度为O(N*logN)
快排代码展示
//先完成荷兰国旗的部分 快排是荷兰国旗的递归形式
static public int[] partion(int[] arr,int left,int right){
int less = left-1;//小于区域右边界
int more = right;//大于区域左边界
//arr[right]是划分值
while (left<more){//当前指针不可以超过more区域,因为里面的数字已经排好序了
if (arr[left]<arr[right]){
//小于标准值 当前值与小于区域右边第一个数交换 小于区域扩大1 left++
ArrayUtils.swap(arr,++less,left++);
}if (arr[left]>arr[right]){
//大于标准值
ArrayUtils.swap(arr,--more,left);
}else {
//等于标准值
left++;
}
}
//因为由始至终标准值arr[right]都没有移动过
// 所以现在就剩最后一步把right移动到大于区域左边界左侧的位置即等于区域的右边界
ArrayUtils.swap(arr,more,right);
return new int[]{less++,more};
}
//快排
static public void quickSort(int[] arr){
if(arr==null||arr.length<2){
return ;
}
quickSort(arr,0,arr.length-1);
}
static public void quickSort(int[] arr,int L,int R){
if(L<R){
int[] partion = partion(arr, L, R);
quickSort(arr,L,partion[0]-1);
quickSort(arr,partion[1]+1,R);
}
}