一、含义
快速排的学名是“切分交换排序”(Partition Exchange Sort ),即通过一个“切分元素”(Partition),将数组递归的切分为两部分,左边小于等于Partition,右边元素大于等于Partition。最终使得整个数组称为有序序列。
性质
- 基于比较的交换排序。
- 不稳定排序。
- 原地排序。
复杂度
- 最差:第一次从最小元素切分,第二次从第二小元素切分等等,此时需要 n22 n 2 2 次比较。打乱数组或者对切分元素随机取值能避免。
- 平均: NlogN N l o g N 。
- 最好:Partition每次都能将数组对半分, Nlog2N N l o g 2 N 。
二. Java实现
public static void sort(Comparable[] arr) {
sort(arr, 0, arr.length - 1);
}
private static void sort(Comparable[] arr, int low, int high) {
if (low >= high) {
return;
}
int r = partition(arr, low, high);
sort(arr, low, r - 1);
sort(arr, r + 1, high);
}
/**
* 切分。
*
* <p>
* <ul>
* <li>选定一个“切分元素”</li>
* <li>外层循环while true</li>
* <li>内存循环:从左至右,当前元素大于等于切分元素时中断</li>
* <li>内存循环:从右至左,当前元素小于等于切分元素时中断</li>
* <li>如果 l>=r 则退出外层循环,否则交换l和r</li>
* <li>将切分元素移动到切分点:即交换low 和 r</li>
* </ul>
*/
private static int partition(Comparable[] arr, int low, int high) {
int l = low, r = high + 1;
Comparable p = arr[low];
while (true) {
while (less(arr[++l], p)) {
if (l == high) {
break;
}
}
while (less(p, arr[--r])) {
// 省略边界检查,因为走不到:p不可能小于自身
}
if (l >= r) {
break;
}
exchange(arr, l, r);
}
exchange(arr, low, r);
return r;
}
public static boolean less(Comparable c1, Comparable c2) {
return c1.compareTo(c2) < 0;
}
public static void exchange(Comparable[] arr, int i, int j) {
Comparable tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}