快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:
- 从数列中挑出一个元素,称为 “基准”(pivot);
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
https://leetcode-cn.com/submissions/detail/117244196/
function quickSort(arr: number[]) {
quick(arr, 0, arr.length - 1)
}
function quick(arr: number[], left: number, right: number) {
const index = partition(arr, left, right)
if(index - 1 > left) {
quick(arr, left, index - 1)
}
if(index < right) {
quick(arr, index, right)
}
}
// 以一个数为基准 将大于基数的元素移到右边 小于基数的元素移到左边
function partition(arr: number[], left: number, right: number): number {
// 取随机值为基准
const random = arr[Math.floor(Math.random() * (right - left + 1)) + left]
let i = left, j = right
while(i <= j) {
// 左边大于基准的值
while(arr[i] < random) {
i++
}
// 右边小于基准的值
while(arr[j] > random) {
j--
}
// 交换
if(i <= j) {
swap(arr, i, j)
i += 1
j -= 1
}
}
return i
}
// 交换数组元素
function swap(arr: number[], i: number, j: number) {
let temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}