function quickselect(nums) {
if (nums.length === 1 || nums.length === 0) return nums;
let left = 0, right = nums.length - 1;
let x = nums[left]
while (left < right) {
while (nums[left] < x){
left++;
}
while (nums[right] > x) {
right--;
}
if (left < right){
let tmp = nums[left];
nums[left] = nums[right];
nums[right] = tmp;
}
}
return [...quickselect(nums.slice(0, right)), nums[right], ...quickselect(nums.slice(right + 1))]
}
console.log(quickselect([5, 3, 8, 4, 2, 7, 1, 6]))
时间复杂度
对于每次划分,都有O(n)的基本操作,由于递归深度为log_2(n),所以总的操作数为 n * log_2(n),即 O(n log n)。这是快速排序在平均情况下的时间复杂度。
最坏的情况分析:当输入数据已经有序或者接近有序时,快速排序的划分可能导致最坏的情况发生,即每次划分只能减少一个元素。这样,需要进行 n-1 次划分,每次划分 O(n) 的基本操作,总的时间复杂度为 (n-1) * n = O(n^2)。
优缺点
优点
- 时间复杂度低: 快排的平均时间复杂度为O(nlogn),比其他常见的排序算法如冒泡排序,选择排序和插入排序等更快
- 原地排序: 快速排序是一种原地排序算法,即不需要额外的存储空间,只需要通过交换数组中的元素来实现排序。
缺点
- 最坏的情况下的时间复杂度较高:在最坏的情况下,时间复杂度为O(n^2) 2.对于小规模数据排序效率低: 对于小规模数据排序效率低:当要排序的数据规模较小的时候,快速排序的效率不如其他简单的排序算法,如插入排序和冒泡排序等。
- 选择基准元素的难度:如果每次选择的基准元素都是当前数组中的最小或最大元素,将会导致快排的性能退化
- 不稳定性:是一种不稳定的排序算法