固定算法,固定思路
- 找到中间位置 midValue
- 遍历数组,小于midValue放在left,否则放在right
- 继续递归。最后concat拼接,返回
细节
- 获取midValue的两种方式
- 使用splice会修改原数组
- 使用slice 不会修改原数组 -- 更加推荐
splice (修改原数组做法)
function quickSort1(arr: number[]): number[] {
let length: number = arr.length
if (length === 0) return arr
let midIndex = Math.floor(length / 2)
let midValue = arr.splice(midIndex, 1)[0]
const left: number[] = []
const right: number[] = []
for (let i = 0
const n = arr[i]
if (n < midValue) {
left.push(n)
} else {
right.push(n)
}
}
return quickSort1(left).concat([midValue], quickSort1(right))
}
const arr4 = [1, 6, 2, 7, 3, 8, 4, 9, 5]
console.info(quickSort1(arr4))
slice (不修改原数组做法)
function quickSort2(arr: number[]): number[] {
let length: number = arr.length
if (length === 0) return arr
let midIndex = Math.floor(length / 2)
let midValue = arr.slice(midIndex, midIndex + 1)[0]
const left: number[] = []
const right: number[] = []
for (let i = 0; i < length; i++) {
if (i !== midIndex) {
const n = arr[i]
if (n < midValue) {
left.push(n)
} else {
right.push(n)
}
}
}
return quickSort1(left).concat([midValue], quickSort1(right))
}
const arr4 = [1, 6, 2, 7, 3, 8, 4, 9, 5]
console.info(quickSort2(arr4))
时间复杂度
- 有遍历 有二分 -- O(n*logn) 或者 O(nlogn)
- 如果是常规排序,嵌套循环,复杂度是O(n^2)
splice 和 slice的区别
- 算法复杂度本身就够高O(n*logn)
- 外加,splice是逐步二分后执行的,二分会快速削减数量级
- 如果单独比较splice和slice,效果会非常明显(splice较慢)
const arr1: number[] = []
for (let i = 0; i < 10 * 10000; i++) {
arr1.push(Math.floor(Math.random() * 1000))
}
console.time('quickSort1 splice')
quickSort1(arr1)
console.timeEnd('quickSort1 splice')
console.time('quickSort2 slice')
quickSort2(arr1)
console.timeEnd('quickSort2 slice')