Open xszi opened 3 years ago
代码实现另一种写法:
const quickSort = (arr) => {
if (arr.length < 2) return arr
let leftArr = []
let rightArr = []
let pivot = arr[0]
arr.forEach(element => {
if (element < pivot) {
leftArr.push(element)
} else if (element > pivot) {
// 必须要加 if (element > pivot), 排除相等情况落入右边,引起Maximum call stack size exceeded
rightArr.push(element)
}
})
return [...quickSort(leftArr), pivot, ...quickSort(rightArr)]
}
由原文最常用的排序——快速排序总结而来:
首先在这个序列中随便找一个数作为基准数(一个作为参照的数)。为了方便,就让第一个数 6 作为基准数吧。
接下来,需要将这个序列中所有比 6 大的数放在 6 的右边,比 6 小的数放在 6 的左边
排序过程
分别从初始序列两端开始“探测”。先 右往左找到一个小于 6 的数停下,再 从左往右找一个大于 6 的数停下,然后交换他们。
定义序列左右两端的 ‘哨兵’
i
和j
,“探测”开始第一次右边‘哨兵’找到 5,左边‘哨兵’找到 7 ,交换之后的序列如下:
第二次右边‘哨兵’找到 9,左边‘哨兵’找到 4 ,“探测”继续
交换之后的序列如下:
此时
i
和j
相遇,探测结束将基准数 6 和相遇位置的数 3 交换位置。得到序列如下:
现在基准数 6 已经归位。此时我们已经将原来的序列,以 6 为分界点拆分成了两个序列,左边的序列是
3 1 2 5 4
,右边的序列是9 7 10 8
。接下来还需要分别处理这两个序列。持续递归让数字归位....最后得到我们最终排序完成的序列:
整个算法处理过程可以以下图来描述:
代码实现
算法复杂度
时间复杂度:O(nlogn) 空间复杂度:O(nlogn)