概述
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
每一次排序都会把选出的key,放入数组中间,左边都是比key小的元素,右边都是比key大的元素,然后以key为分割点,对 [0, k-1] 和 [k+1, length] 进行如上操作,直到数组中只有一个元素。
时间复杂度
时间复杂度为:O(nlogn)
算法稳定性
快速排序有两个方向,左边的i下标一直往右走,当a[i] <= a[center_index],其中center_index是中枢元素的数组下标,一般取为数组第0个元素。而右边的j下标一直往左走,当a[j] > a[center_index]。如果i和j都走不动了,i <= j, 交换a[i]和a[j],重复上面的过程,直到i>j。 交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列为 5 3 3 4 3 8 9 10 11, 现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱,所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j] 交换的时刻。
示例代码
/**
* 快速排序
* @author 吴庆龙
* Date: 2018/8/2
* Time: 11:17
*/
public class QuickSort {
public static void main(String[] args) {
int[] array = {7,3,2,4,1,8,0,9,5,6};
sort(array, 0, array.length - 1);
for (int i : array) {
System.out.print(i + " ");
}
System.out.println();
}
private static void sort(int[] array, int left, int right) {
// 递归终止条件
if (left >= right) {
return;
}
// 左边索引
int l = left;
// 右边索引
int r = right;
// 关键字
int key = array[left];
while (l < r) {
// 从右向左查找比 key 小的数
while (l < r && key <= array[r]) {
r--;
}
if (l < r) {
// 把数放入array[l]的位置(小的放到数组的左边)
array[l] = array[r];
l++;
}
// 从右向左查找比 key 大的数
while (l < r && key >= array[l]) {
l++;
}
if (l < r) {
// 把数放入array[r]的位置(大的放到数组的右边)
array[r] = array[l];
r--;
}
}
// 确定key的位置, 并赋值
array[l] = key;
sort(array, left, l - 1);
sort(array, l + 1, right);
}
}