算法思想

利用“分治”的思想,选择一个哨兵数字,将原先的数据分为两部分(大于哨兵和小于哨兵)。
重复这个过程,直到不能为止

时间复杂度

在最好的情况下,假设 快速排序 - 图1 为排序的时间,那么有:
快速排序 - 图2
那么就可以推导出
快速排序 - 图3
快速排序 - 图4
那么在最差的情况下呢
快速排序 - 图5
就退化成了 快速排序 - 图6

实现代码

  1. function quickSort(nums, begin, end) {
  2. if (begin < end) {
  3. let q = partition(nums, begin, end);
  4. quickSort(nums, begin, q - 1);
  5. quickSort(nums, q + 1, end);
  6. }
  7. }
  8. function partition(nums, begin, end) {
  9. let pivot = Math.floor(Math.random() * (end - begin)) + begin;
  10. swap(nums, pivot, end);
  11. let j = begin - 1;
  12. for (let i = begin; i < end; ++i) {
  13. if (nums[i] < nums[end]) {
  14. j++;
  15. swap(nums, i, j);
  16. }
  17. }
  18. swap(nums, j + 1, end);
  19. return j + 1;
  20. }
  21. function swap(nums, a, b) {
  22. let t = nums[a]; nums[a] = nums[b]; nums[b] = t;
  23. }

变种:快速选择

查找数组内的第 K 大数:先选择一个哨兵,然后将数组分为两部分,根据返回 q 的位置:

  • q = k,那么返回 q
  • q < k,那么继续分右边
  • q > k,那么继续分左边