快速排序(Quicksort)是对冒泡排序的一种改进。
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
——来自百度百科
图解算法
图解说明
1. 假定L位标识的元素为a[left],R位标识的元素为a[right],基准值为base。在图解过程中,我们首先将首尾分别标记为a[left]和a[right],并令a[left]为基准值。
2. 从R位向左寻找比base值小的数,即不断重复right–(循环),直到找到合适的值,将此时R位的元素a[right]赋值给此时的L位a[left],即a[left]=a[right]。
3. 从L位向右寻找比base值大的数,即不断重复left++(循环),直到找到合适的值,将此时L位的元素a[left]赋值给此时的R位a[right],即a[right]=a[left]。
4. 不断重复2、3的步骤(循环),不断将小于base的值移到当时的L位,将大于base的值移到当时的R位,直到LR位重合则停止,即循环时left一直是小于right的。
5. 将base的值传给LR重合位,即a[left]=base,或a[right]=base。此时,基准位左侧的数都比基准位小,右侧的数都比基准位大。
6. 将基准位左右侧的数列当成2个独立的数组,分别重复以上步骤排好各自的基准位,此时各自基准位的左侧都是小于基准位的数,右侧都是大于基准位的数。然后将各自基准位左右两侧再次当成2个独立的数组,重复步骤……直到每个独立数组元素只有1个,则该独立数组视为已排序。又因各基准位左侧小,右侧大,所以合并所有单元素独立数组后,源数组即已排好序。(递归)
核心代码
//用quickSort(a, 0, a.length - 1)调用,a为要排序的数组。
public static void quickSort(int[] a, int left, int right) {
if (left < right) {
int base = a[left];
int sLeft = left;
int sRight = right;
while (sLeft < sRight) {
while (sLeft < sRight && a[sRight] >= base) {
sRight--;
}
a[sLeft] = a[sRight];
while (sLeft < sRight && a[sLeft] <= base) {
sLeft++;
}
a[sRight] = a[sLeft];
}
a[sLeft] = base;
quickSort(a, left, sLeft - 1);
quickSort(a, sLeft + 1, right);
}
}
优化一下以上代码:
//用quickSort(a, 0, a.length - 1)调用,a为要排序的数组。
public static void quickSort(int[] a, int left, int right) {
//见图解说明,左位要小于右位,当等于时,说明所有位已查找完。
if (left < right) {
//每次的基准位下标
int baseIndex = devision(a, left, right);
//基准位左侧的数组再细分
quickSort(a, left, baseIndex - 1);
//基准位右侧的数组再细分
quickSort(a, baseIndex + 1, right);
}
}
private static int devision(int[] a, int left, int right) {
//令首位为基准位,其值为基准值
int base = a[left];
while (left < right) {
//从右向左寻找比base小的数,如有则赋值给L位
while (left < right && a[right] >= base) {
right--;
}
a[left] = a[right];
//从左向右寻找比base大的数,如有则赋值给R位
while (left < right && a[left] <= base) {
left++;
}
a[right] = a[left];
}
//寻找完后,将基准值赋值给LR重合位。
a[left] = base;
//返回此时的LR重合位作为递归划分左右数组的中心点。
return left;
}
注明
基准位没有固定的选值,你可以选择任何一个位置作为基准位。
参考文章
说明
本文为个人学习笔记,如有细节错误或描述歧义,请留言告知,谢谢!
本文首发于博客专栏: http://Windows9.Win/quick_sort_algorithm