快排

296 阅读2分钟
  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)。

优缺点

优点

  1. 时间复杂度低: 快排的平均时间复杂度为O(nlogn),比其他常见的排序算法如冒泡排序,选择排序和插入排序等更快
  2. 原地排序: 快速排序是一种原地排序算法,即不需要额外的存储空间,只需要通过交换数组中的元素来实现排序。

缺点

  1. 最坏的情况下的时间复杂度较高:在最坏的情况下,时间复杂度为O(n^2) 2.对于小规模数据排序效率低: 对于小规模数据排序效率低:当要排序的数据规模较小的时候,快速排序的效率不如其他简单的排序算法,如插入排序和冒泡排序等。
  2. 选择基准元素的难度:如果每次选择的基准元素都是当前数组中的最小或最大元素,将会导致快排的性能退化
  3. 不稳定性:是一种不稳定的排序算法

对快排进行优化