快排能够说是一道必知的常见面试题,同时也有多种实现方式。在这篇文章中,我使用的是随机三路快排。面试
之因此使用随机快速排序而不是普通的快排。是由于前者可使得数列有序的几率下降,从而使随机快速排序平均速度是比快速排序要快的。具体的二者的性能差异能够看下这篇文章:数组
blog.csdn.net/haelang/art…bash
talk id cheap,show the code。一共 20+ 行代码,每行代码都有注释。其中交换数组元素位置,打印元素的方法我就没贴了,代码太长大家也不方便看。微信
PS:代码下面有执行流程图,结合代码来看比较容易理解。less
public static void main(String[] args) {
// 测试数据
int[] arr = new int[]{5, 3, 6, 4};
// 执行快排
quickSort(arr, 0, arr.length - 1);
// 打印数组元素
printArray(arr);
}
private static void quickSort(int[] arr, int l, int r) {
if (l < r) {
// 随机取须要排序的数组中的一个元素和数组的最后一个元素交换,做为划分值
swap(arr, l + (int) (Math.random() * (r - l + 1)), r);
// 获得数组元素中等于划分值的区域
int[] part = partition(arr, l, r);
// 小于等于划分值的区域
quickSort(arr, l, part[0] - 1);
// 大于划分值的区域
quickSort(arr, part[1] + 1, r);
}
}
private static int[] partition(int[] arr, int l, int r) {
// 初始化小于等于划分值区域的当前下标,默认是数组第一个元素的前一个位置
int less = l - 1;
// 初始化大于划分值区域的当前下标,默认是数组最后一个元素的位置,同时也是划分值的位置,但该值并不属于大于划分值的区域,因此要在最后进行移动
int more = r;
// 当前下标小于大于划分值区域的下标时
while (l < more) {
// 当前值比划分值小,当前值和小于等于划分值区域的右边第一个值进行交换,小于等于划分值区域右移1个下标,当前下标+1
if (arr[l] < arr[r]) {
swap(arr, l++, ++less);
// 当前值比划分值大,当前值和大于划分值区域的左边第一个值进行交换,大于划分值的区域左移1个下标
} else if (arr[l] > arr[r]) {
swap(arr, l, --more);
// 当前值等于划分值,当前下标+1
} else {
// 当前下标+1
l++;
}
}
// 将划分值和大于划分值区域中,最接近划分值区域的元素交换。至此完成全部值的区域划分
swap(arr, more, r);
// 返回等于划分值的区域
return new int[]{less + 1, more};
}
复制代码
下面我会画个流程图帮你们理解一下,测试数据和代码同样。dom
假设代码执行完 13 行后,测试数据的顺序依旧不变,即为 {5,3,6,4}。性能
接下来在执行 partition() 方法的过程当中,数组元素的状况以下图所示(灵魂写手求轻喷) 测试
好了,以上就是本文的所有内容,咱们下篇文章再见,捂脸逃~ui
PS:本文原创发布于微信公众号「不仅Java」,后台回复「Java」,送你 13 本 Java 经典电子书。公众号专一分享 Java 干货、读书笔记、成长思考spa