public static void quickSort() {// 快速排序 { int[] array = {2, 34, 5, 1, 62, 56, 7, 3}; quickRecursion(array, 0, array.length - 1); System.out.println(Arrays.toString(array)); } } public static void quickRecursion(int[] array, int p, int r) { if (p < r) { int part = partition(array, p, r);// 分割元素的下标 quickRecursion(array, p, part - 1);// 下标之前的元素进行排序 quickRecursion(array, part + 1, r);// 下标之后的元素进行排序 } } public static int partition(int[] array, int p, int r) {// 获取分割元素的下标 int part = array[r];// 分割元素,取数组的最后一位。 int i = p;// 分割元素的下标。 for (int j = p; j < r; j++) { if (array[j] < part) {// 小于分割元素的依次和左边的元素交换。 exchange(i, j, array); i++;// 交换之后下标加1。 } } exchange(i,r,array);// 分割元素和分割下标上的元素交换。 return i;// 返回分割元素的下标 }
快速排序(Quicksort)的原理:
我们习惯性把它简称为“快排”。快排利用的也是分治思想。乍看起来,它有点像归并排序,但是思路其实完全不一
样。我们待会会讲两者的区别。现在,我们先来看下快排的核心思想。
快排的思想是这样的:如果要排序数组中下标从 p 到 r 之间的一组数据,我们选择 p 到 r 之间的任意一个数据作
为 pivot(分区点)。
我们遍历 p 到 r 之间的数据,将小于 pivot 的放到左边,将大于 pivot 的放到右边,将 pivot 放到中间。经过
这一步骤之后,数组 p 到 r 之间的数据就被分成了三个部分,前面 p 到 q-1 之间都是小于 pivot 的,中间是
pivot,后面的 q+1 到 r 之间是大于 pivot 的。
根据分治、递归的处理思想,我们可以用递归排序下标从 p 到 q-1 之间的数据和下标从 q+1 到 r 之间的数据,直
到区间缩小为 1,就说明所有的数据都有序了。
如果我们用递推公式来将上面的过程写出来的话,就是这样:
递推公式:
quick_sort(p…r) = quick_sort(p…q-1) + quick_sort(q+1… r)
终止条件:
p >= r
快速排序总结:
空间复杂度为O(1),
是不稳定排序,
时间复杂度:最大为O(n2),平均为O(nlogn)。
应用:
当需要查找第K大的值时,可以先把数组分为3段,如果K正好等于分割线那么复杂度为O(1),大于分割线为O(n)