快速排序——acwing算法基础课笔记

发布时间 2023-11-07 11:09:05作者: zerocloud01

课堂内容+个人思考,个人笔记,但是欢迎补充、批评、指正。

快速排序基于分治的思想

平均时间复杂度O(nlogn)

已知数组q[]

 步骤:

1、确定分界点(x):

   (1)首元素q[l];  (2)尾元素q[r];  (3)中值q[(l+r)/2];  (4)随机;

2、调整区间

  将区间通过x值划分为两部分(长度不一定相等),使得第一个区间所有数均小于等于x。第二个区间所有数均大于等于x。

  注:若某数等于x,在左在右均可。

3、递归处理左右两端

  左右重复步骤2。

方法(调整区间):

暴力做法:

 

优美做法:

利用两个指针i,j。

1、i从首位向右扫描,数据<x时,i继续,数据>=x时停止;

2、j从末位向左扫描,数据>x时,j继续,数据<=x时停止;

3、交换i,j的值;

4、重复1~3,直到i、j相遇(穿过)。

注:数据并没有被抽离数组,分界点仍在数据中被排序;

  若i/j仅一者停止,那么j/i会一直移动到i/j,此时左右区间满足条件。

  有很多边界问题,最好背过模版。

  写过几次就错了几次。

模板:

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;//区间无数据(1/0个)时,结束

    int i = l - 1, j = r + 1, x = q[l + r >> 1];
  /*因为循环体i、j先++、--了一次*/
while (i < j) { do i ++ ; while (q[i] < x); do j -- ; while (q[j] > x); if (i < j) swap(q[i], q[j]);//未相遇时,交换元素 } quick_sort(q, l, j), quick_sort(q, j + 1, r);//迭代左右两区间 }
//说实话,这代码真好看。

对于最后迭代的部分取i还是取j:

  取i是x不取左边界(l),取j时x不取右边界(r)。

  所以我无脑取中值。