快速排序
快速排序是实践中的一种快速的排序算法。它的平均运行时间是O(N Log N),最坏运行时间是(N²)。
思路
在数组中选择一个枢纽元(基数),经过一定的处理的后,枢纽元所在位置的左侧均小于等于枢纽元,右侧均大于等于枢纽元;然后对左侧和右侧重复上一步骤。
枢纽元的选择
枢纽元的选择有三种方法:
1、选择最小或者最大的索引
2、选择随机的索引
3、在最小索引、最大索引、中间索引中选出一个中位数,中位数所在的索引选作枢纽元
一般认为第三种方法是最好的。
使枢纽元左右侧符合规则
有许多种方法对枢纽元进行处理,最简单的是直接创建一个存放小元素的集合和一个存放大原素的集合,对所有元素比较并放入相应的集合,最后再按顺序取出。但是这样会浪费极大的空间,现在介绍另一种不需要任何多余空间的一种方法:
1、将枢纽元与最大索引上的值互换(枢纽元现在在最大索引上了)
2、记录一个左指针leftPointer(最小索引),记录一个右指针rightPointer(除枢纽元以外的最大索引,也就是最大索引-1)
3、左指针向右移动,找到第一个大于枢纽元的值的索引,右指针向左移动,找到第一个小于枢纽元的索引
4、若左指针小于右指针,则交换左指针和右指针上的值,并使两个指针都指向下一个索引,重复步骤2、步骤3;
若左指针等于右指针,此时,如果指针对应的值小于枢纽元,则使左指针移动到下一个索引,不再重复步骤2、3;
若左指针大于右指针,什么也不做,不再重复步骤2、3
5、将左指针(此时左指针指向从左至右第一个大于枢纽元的值)上的值和最大索引上的值(枢纽元)交换
6、结束,此时符合枢纽元的规则
实现
代码如下:
public class QuickSort {
public static void main(String[] args) {
int[] arr = getArr(100_000_000);
System.out.println("开始");
long start = System.currentTimeMillis();
quickSort(arr);
long end = System.currentTimeMillis();
System.out.println("结束:"+(end-start));
testSort(arr);
}
/**
* 验证数组排序的正确性
* @param arr
*/
public static void testSort(int[] arr) {
for(int i=0;i<arr.length