快速排序被应用非常广泛,而且是一种原地、不稳定的排序算法。一直都知道这个名词,只知道这种排序很快!每次面试的时候也说不上个所以然来。索性手动实现一遍,也多亏了王争的数据结构和算法之美专栏。嗯~ o( ̄▽ ̄)o确实理解了好长时间!
首先快排的思想是这样的:如果要排序数组中下标从 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
将递推公式转化成递归代码。
// 快速排序,A 是数组,n 表示数组的大小
quick_sort(A, n) {
quick_sort_c(A, 0, n-1)
}
// 快速排序递归函数,p,r 为下标
quick_sort_c(A, p, r) {
if p >= r then return
q = partition(A, p, r) // 获取分区点
quick_sort_c(A, p, q-1)
quick_sort_c(A, q+1, r)
}
这里有个核心方法partition() 函数就需要很多额外的内存空间,为了实现快排是原地排序算法,那它的空间复杂度得是 O(1),那 partition() 分区函数就不能占用太多额外的内存空间,我们就需要在 A[p…r] 的原地完成分区操作。同时快速排序的时间复杂度为O(nlogn),最坏的情况是O(n2),空间复杂度是O(n)。
用java来实现:
package com.sqt;
import java.util.Arrays;
/**
* @Description:
* @author: ListenerSun(男, 未婚) 微信:810548252
* @Date: Created in 2019-12-28 18:47
*/
public class QuickSort {
public static void main(String[] args) {
int[] arr = {1,8,23,7,3,5};
quickSort(arr,6);
System.out.println(Arrays.toString(arr));
}
/**
* 快速排序
*
* @param arr 数组
* @param n 数组大小
*/
public static void quickSort(int[] arr, int n) {
quickSortPar(arr, 0, n - 1);
}
// 快速排序递归函数,p,r为下标
private static void quickSortPar(int[] arr, int p, int r) {
//p = r 时 只剩一个元素,不用排序了
if (p >= r) {
return;
}
//获取 分区 点下标
int q = partition(arr, p, r);
quickSortPar(arr,p,q-1);
quickSortPar(arr,q+1,r);
}
/** 获取分区点
* 分区点 左边的元素都比分区点元素小,右边反之
* @param arr
* @param p
* @param r
* @return
*/
private static int partition(int[] arr, int p, int r) {
//为了节省内存空间 直接在原数组内操作
// i 用来存储 分界值的下标
int i = p;
// 分区点 元素的值
int pro = arr[r];
for (int j = p; j < r; j++) {
if (arr[j] < pro) {
if (i == j) {
//i == j 时,此时元素为第一个元素,需要将 i 往前移动一位
i++;
} else {
//将 arr[j] 跟 arr[i] 调换位置
int temp = arr[i];
arr[i++] = arr[j];
arr[j] = temp;
}
}
}
//将 arr[r] 跟 arr[i] 调换位置
int temp = arr[i];
arr[i] = arr[r];
arr[r] = temp;
return i;
}
}