Quick Sort,又称分区交换排序(partition-exchange sort),最早由东尼·霍尔提出。
快速排序使用分治法(Divide and conquer)策略来把一个序列分为较小和较大的2个子序列,然后递归地排序两个子序列。(分而治之)
快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。
算法步骤
- 从数列中挑出一个元素,称为 "基准"(pivot);
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
复杂度
标题 | 数据 |
---|---|
平均时间复杂度 | O(nlogn) |
最好情况 | O(nlogn) |
最坏情况 | O(n²) |
空间复杂度 | O(nlogn) |
排序方式 | In-place |
稳定性 | 不稳定 |
代码演示
function quickSort(list) {
function Sort(list, start, end) {
//数组长度小于一,退出循环
if (end - start < 1) return;
//获取到基准的下标,数组分开继续处理
let mid = partition(list, start, end);
//比基准小的进行排序,重复找基准-》排序
Sort(list, start, mid - 1);
//比基准大的进行排序,重复找基准-》排序
Sort(list, mid + 1, end);
return list
}
Sort(list, 0, list.length - 1)
return list
}
function partition(list, start, end) {
//设置数组最后一位为基准值
let pivot = list[end],
index = start;
for (let i = start; i <= end; i++) {
//当前的值比基准小,放在左边,交换位置
if (list[i] <= pivot) {
//此时进行交换,比基准小的在左边,大的在右边
[list[i], list[index]] = [list[index], list[i]];
index++
}
}
//最后一次比较相当于自己和自己比较(end和pivot),所以要减1,得到基准的位置
return index - 1
}