面试-----快速排序看这一篇就够了

面试-----快速排序看这一篇就够了

快速排序(Quicksort)是对冒泡排序的一种改进。

快速排序由C. A. R. Hoare在1962年提出。

它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

  1. 快排的思想是分治
  2. 我们有一个待排序的数组,长度为n。选定一个基准,将数组分成左右两部分,左边的数小于基准,右边的数大于基准。
  3. 然后我们分别看分割后左右两部分数组,如果元素个数大于1,就再次分割。
  4. 直到最后,我们得到了n个数组,每个数组含有1个元素。
  5. 这n个数组中,每两个挨着的,都是排好序的,所以整体有序。
  6. 最好情况下,每次将原来的数组分成两份,第二次将两份成四份…最后一个元素一份。每次分割是O(n),
  7. 假设分割次数为k,则2的k次方等于n,k = logn。每次分割的总时间复杂度是O(n),所以说,平均复杂度是O(n*logn)。
  8. 最坏就是原数组有序,每次只能分割开1个元素,需要分割n次,时间复杂度是O(n^2)。
    在这里插入图片描述

代码一:按照思路直接编写,有O(N)的额外空间。

void quick_sort(int a[], int l, int r) {
  if (l >= r) return;

  int x = a[l];
  vector<int> left;
  vector<int> right;
  
  for (int i = l + 1; i <= r; i++) {
    if (a[i] <= x)
      left.push_back(a[i]);
    else right.push_back(a[i]);
  }

  int k = l;
  for (int i = 0; i < left.size(); i++) {
    a[k] = left[i];
    k++;
  }
  a[k++] = x;
  for (int i = 0; i < right.size(); i++) {
    a[k] = right[i];
    k++;
  }
  
  quick_sort(a, l, l + left.size() - 1);
  quick_sort(a, l + left.size() + 1, r);
}

代码二:改进,空间复杂度降为O(1)

void quick_sort(int a[], int l, int r) {
  if (l >= r) return;

  int x = a[l];
  int i = l - 1, j = r + 1;
  while (i < j) {
    while (a[++i] < x);
    while (a[--j] > x);
    if (i < j) {
      int temp = a[i];
      a[i] = a[j];
      a[j] = temp;
    }
  }
  quick_sort(a, l, j);
  quick_sort(a, j + 1, r);
}

快排边界情况较多,理解后直接背过模板代码。


欢迎关注公众号,每周更新面试高频算法题。原理,代码,复杂度,优化等多方面讲解。

个人微信,欢迎交流在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值