快速排序也是基于分治法来实现的,主要实现就是通过选择一个基准元素,把数组分成两部分,一部分小于基准值,放它左边,一部分大于基准值,放它右边。这个步骤执行完的时候,基准值的位置已经固定,它后面不会再处理了。然后分别对左边部分选一个新的基准值,继续分为两部分,然后对这两部分都选出新的基准值……基准值不要自己设定一个值,最好是从数组中取,可以设为区域内的第一个元素,或者最后一个元素。

实现

Java实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
* 快速排序
*/
public static void quickSort(int [] arr, int left, int right){
if(left < right){
int index = partition(arr, left, right);
// 对基准值两边的元素再继续进行分别处理
quickSort(arr, left, index - 1);
quickSort(arr, index + 1, right);
}
}

/**
* 默认获取第一个元素为基准值,返回基准值的位置下标
*/
public static int partition(int [] arr, int left, int right){
// 选择区间内第一个元素作为基准值
int baseValue = arr[left];
int index = left + 1;
for (int i = index; i <= right; i++) {
// 把所有小于基准值的元素从左依次放好
if(arr[i] < baseValue){
// 交换元素位置
int temp = arr[i];
arr[i] = arr[index];
arr[index] = temp;
index++;
}
}

// 为什么要减一,因为这个index-1这个位置的元素是小于基准值的
// 如果碰到特殊情况怎么办?比如arr[left]恰好是最小的一个元素,此时index-1刚好是left,所以也不影响最终结果
index--;

// 把基准值放到中间去
// 和left上的元素(也就是基准值)交换位置以后,恰好left-right区间内,基准值左边的都小于它,右边的元素都大于它
arr[left] = arr[index];
arr[index] = baseValue;

// 返回基准值的位置下标
return index;
}

时间复杂度呢主要就是分解和合并,分解的时候每个数组分成2部分,然后不断分割,最差情况是O(n),最差情况是为O(logn)。合并的时候时间复杂度为O(n),总体的最差时间复杂度O(n²),平均时间复杂度为O(nlogn),网上资料说快速排序虽然时间复杂度也是O(nlogn),但是一般会比其他O(nlogn)的排序算法更快,感兴趣的可以网上继续了解。空间复杂度的话就是递归的深度,最好情况是O(logn),最差情况是O(n),平均情况是O(logn)。由于交换位置可能会破坏稳定性,所以快速排序是不稳定的

总结

时间复杂度(平均):O(nlogn)

空间复杂度(平均):O(nlogn)

稳定性:不稳定


今日总访问量 加载中…
今日总访客数 加载中…
本站总访问量 加载中…
本站总访客数 加载中…
本页总阅读量 加载中…
本页总访客数 加载中…