一、🐶 快速排序的原理
- 分区: 从数组中任意选择一个基准,所有比基准小的元素放到基准前面,比基准大的元素放到基准的后面
- 递归:递归地对基准前后的子数组进行分区
快排实现方式一代码如下(不考虑空间消耗):
js
Array.prototype.quickSort = function () {
const rec = (arr) => {
// 预防数组是空的或者只有一个元素, 当所有元素都大于等于基准值就会产生空的数组
if(arr.length === 1 || arr.length === 0) { return arr; }
const left = [];
const right = [];
//以第一个元素作为基准值
const mid = arr[0];
//小于基准值的放左边,大于基准值的放右边
for(let i = 1; i < arr.length; ++i) {
if(arr[i] < mid) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
//递归调用,最后放回数组
return [...rec(left),mid,...rec(right)];
};
const res = rec(this);
res.forEach((n,i) => { this[i] = n; })
}
const arr = [2,3,4,5,3,1];
arr.quickSort();
console.log(arr);
总结:简明易懂,好理解,好写,适合面试的时候手撸代码。
时间复杂度
- 最好时间复杂度为O(nlog₂n)
- 最坏时间复杂度为O(n²)
- 平均时间复杂度为O(nlog₂n)
空间复杂度
需要额外的left和right临时空间所以空间复杂度为O(nlog₂n)
稳定性
代码第8行约定以第一个元素作为基准值,代码11-15行约定,当数据等于mid的时候放到right区间,所以相同元素位置前后不会改变。属于稳定的排序算法
快排实现方式二代码如下(不占用额外的空间消耗):
js
function quickSort(arr, low, high) {
if (low < high) {
let pivotposition = partition(arr, low, high);
quickSort(arr, low, pivotposition-1);
quickSort(arr, pivotposition+1, high);
}
}
function partition(arr, low, high) {
let temp = arr[low];
while(low < high) {
// 此时左边位置为空,所以从右边去找,如果arr[high] >= temp移动指针接着往前找
while(low < high && arr[high] >= temp){
high--;
continue;
}
// 此时左边位置为空,从右边去找,如果arr[high] < temp,则把它赋值给左边,此时右边的位置为空,跳出循环,重头再来
while(low < high && arr[high] < temp){
arr[low] = arr[high];
low++;
break;
}
// 此时右边为空,去左边找,找到arr[low] <= temp,移动指针接着往后找
while(low < high && arr[low] <= temp){
low++;
continue;
}
// // 此时右边为空,去左边找,找到arr[low] > temp,把它赋值到右边,跳出循环,重头再来
while(low < high && arr[low] > temp){
arr[high] = arr[low];
high--;
break;
}
}
arr[low] = temp;
return low;
}
- 我们遍历 p 到 r 之间的数据,将小于 pivot 的放到左边,将大于 pivot 的放到右边,将 pivot 放到中间。
- 经过这一步骤之后,数组 p 到 r 之间的数据就被分成了三个部分,前面 p 到 q-1 之间都是小于 pivot 的,中间是 pivot,后面的 q+1 到 r 之间是大于 pivot 的。
- 据分治、递归的处理思想,我们可以用递归排序下标从 p 到 q-1 之间的数据和下标从 q+1 到 r 之间的数据,直到区间缩小为 1,就说明所有的数据都有序了。
时间复杂度
- 分区均衡,最好时间复杂度为O(nlog₂n)
- 分区不均衡,最坏时间复杂度为O(n²)
- 平均时间复杂度为O(nlog₂n)
空间复杂度
只需要一个temp空间,所以空间复杂度为O(1)
稳定性
涉及到左右位置的交换,所以排序过程中2个相同的数位置会交换,是不稳定的排序算法。