快速排序法
原理:
- 首先要从一列数据中取出一个基准数
- 小于这个基准数的全放到左边,大于等于这个基准数的全放到右边
- 再对左右两个区间继续重复第2步,知道个区间只有一个数字
- 最后将有序的区间合并起来即可
代码实现:
const arr = [31, 34, 23, 2, 15, 67, 54, 99]
function quickSort(arr) {
// 1.找基准数,并且将小于等于基准数的全部放到左边(左数组)
// 将大于等于基准数的全部放到右边(右数组)
let baseNum = arr[0] // 基准数
let leftArr = [] // 左数组
let rightArr = [] // 右数组
for (let i = 1; i < arr.length; i++) {
// 比基准数小的放在左数组,比基准数大的放在右数组
if (arr[i] < baseNum) {
leftArr.push(arr[i])
} else {
rightArr.push(arr[i])
}
}
// 2.对左右数组分别快排、返回排序好的左右数组
// (条件:数组中的元素大于等于两个)
if (leftArr.length >= 2) {
leftArr = quickSort(leftArr)
}
if (rightArr.length >= 2) {
rightArr = quickSort(rightArr)
}
// 3.合并排序好的左数组、基准数、右数组,并且返回
return leftArr.concat(baseNum, rightArr)
}
console.log(quickSort(arr))
结果演示:
时间复杂度:
最好的情况:每一次的baseNum都恰好平分整个数组,O(nlogn)
最坏的情况:每一次的baseNum都是数组中的最大值/最小值,O(n2)
空间复杂度:
最好的情况:每一次base值都刚好平分整个数组,递归树的深度O(logn)
最坏的情况:每一次base值都是数组中的最大/最小值,递归树的深度O(n)
稳定性:
快速排序是不稳定的,因为有相等的num时候,可能他们俩会交换位置