一、中心思想:分治
- 确定分界点x:q[l],q[r],q[(l+r)/2],或者任取一点
- 调整区间,小于等于x的放在x左边,大于x的放在x右边
- 递归将左边和右边分别排好序
二、核心内容:调整区间
- 暴力做法:
- 另建两个数组a[],b[]
- 对q[l]到q[r]扫描,小于等于x的丢到a,大于x的丢到b
- 先将a存进q,再接着存b
虽然很不优雅,但是咱不差这内存,时间复杂度是一样的0.0
- 优雅的做法:
- 在l处和r处设置一个“指针”i,j
- 如果i处小于等于x,则i右移,直到i处大于x停下;然后判断j处,如果j处大于x,则j左移,直到j处小于等于x停下
- 终止条件:i=j
三、上代码!
void quick_sort(int q[], int l, int r)
{
if (l >= r)
return;
int x = q[(l + r) / 2], i = l - 1, j = r + 1; //这里将l-1,i+1的原因是下面采用的是do-while循环
while (i < j)
{
do
i++;
while (q[i] <= x); //采用do-while循环的原因是需要先移动再判断(判断完一次后下一次判断前需要先移动)
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); //对x左边和右边分别递归
}
四、配套练习
AcWing785https://www.acwing.com/activity/content/problem/content/819/AcWing786https://www.acwing.com/activity/content/problem/content/820/