# 解题思路 or 实现原理
快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下, 排序 n
个项目要 Ο(nlogn)
次比较。在最坏状况下则需要 Ο(n2)
次比较, 但这种状况并不常见。事实上, 快速排序通常明显比其他 Ο(nlogn)
算法更快, 因为它的内部循环(inner loop
)可以在大部分的架构上很有效率地被实现出来。
快速排序使用分治法(Divide and conquer
)策略来把一个串行(list
)分为两个子串行(sub-lists
)。
快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看, 快速排序应该算是在冒泡排序基础上的递归分治法。
快速排序的最坏运行情况是 O(n²)
, 比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn)
, 且 O(nlogn)
记号中隐含的常数因子很小, 比复杂度稳定等于 O(nlogn)
的归并排序要小很多。所以, 对绝大多数顺序性较弱的随机数列而言, 快速排序总是优于归并排序。
# 算法步骤
从数列中挑出一个元素, 称为'基准' (
pivot
);重新排序数列, 所有元素比基准值小的摆放在基准前面, 所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后, 该基准就处于数列的中间位置。这个称为分区(
partition
)操作;递归地(
recursive
)把小于基准值元素的子数列和大于基准值元素的子数列排序;
递归的最底部情形, 是数列的大小是零或一, 也就是永远都已经被排序好了。虽然一直递归下去, 但是这个算法总会退出, 因为在每次的迭代(iteration
)中, 它至少会把一个元素摆到它最后的位置去。
# 实现代码
/*
* @Author: Rainy
* @Date: 2019-11-14 19:25:01
* @LastEditors: Rainy
* @LastEditTime: 2019-11-24 20:51:18
*/
import { NumberArrayMap } from 'types';
export function quickSort(arr: NumberArrayMap, left?: number, right?: number) {
let len: number = arr.length;
let partitionIndex: number = 0;
let lIndex: number = typeof left !== 'number' ? 0 : left;
let rIndex: number = typeof right !== 'number' ? len - 1 : right;
if (lIndex < rIndex) {
partitionIndex = partition(arr, lIndex, rIndex);
quickSort(arr, lIndex, partitionIndex - 1);
quickSort(arr, partitionIndex + 1, rIndex);
}
return arr;
}
function partition(arr: NumberArrayMap, left: number, right: number) {
let pivot: number = left;
let index: number = pivot + 1;
for (let i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) {
[arr[i], arr[index]] = [arr[index], arr[i]];
index++;
}
}
[arr[pivot], arr[index - 1]] = [arr[index - 1], arr[pivot]];
return index - 1;
}
// export function quickSort(arr: NumberArrayMap): NumberArrayMap {
// let len = arr.length;
// if (len < 2) {
// return arr;
// }
// let pivotIndex: number = Math.floor(len / 2);
// let pivot: number = arr.splice(pivotIndex, 1)[0];
// let left: NumberArrayMap = [];
// let right: NumberArrayMap = [];
// for (let i = 0; i < len; i++) {
// if (arr[i] < pivot) {
// left.push(arr[i]);
// } else {
// right.push(arr[i]);
// }
// }
// return quickSort(left).concat([pivot], quickSort(right));
// }
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
43
44
45
46
47
48
49
50
51
52
53
54
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
43
44
45
46
47
48
49
50
51
52
53
54