本文是在听过AcWing算法基础课程之后留下自用的笔记,如有侵权会删除。感觉AcWing的课还是蛮好的,课程地址如下:
https://www.acwing.com/activity/content/introduction/11/
1 基本思想
- 核心思想:分治
- Step1:确定分界点: q [ l ] , q [ ( l + r ) / 2 ] , q [ r ] q[l], q[(l+r)/2], q[r] q[l],q[(l+r)/2],q[r]等均可(l为左边界,r为右边界),要看边界情况选择(见后文)
- Step2:调整范围:比分界点的值(记为val)小的放左边,大的放右边(核心)
- Step3:递归处理左右两段
2 调整范围的方法
2.1 暴力
- Step1:新建两个数组a,b
- Step2:遍历q,比val小的放a,大的放b
- Step3:拼接a,b
2.2 双指针
- Step1:左指针i,右指针j
- Step2:++i,直到遇到第一个大于等于val的
- Step3:–j,直到遇到第一个小于等于val的
- Step4:
swap(q[i], q[j])
3 代码
3.1 版本1
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int n;
int q[N];
void quickSort(int q[], int l, int r){
if (l >= r)
return;
int val = q[(l + r) / 2];
int i = l - 1;
int j = r + 1;
while (i < j){
do i++; while(q[i] < val);
do j--; while(q[j] > val);
if (i < j) swap(q[i], q[j]);
}
quickSort(q, l, j);
quickSort(q, j+1, r);
}
int main(){
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d", &q[i]);
quickSort(q, 0, n-1);
for (int i = 0; i < n; i++) printf("%d ", q[i]);
}
边界问题:
这里分界点不能选为r,即val不可以等于q[r]
3.2 版本2:
void quickSort(int q[], int l, int r){
if (l >= r)
return;
int val = q[(l + r) / 2];
int i = l - 1;
int j = r + 1;
while (i < j){
do i++; while(q[i] < val);
do j--; while(q[j] > val);
if (i < j) swap(q[i], q[j]);
}
quickSort(q, l, i-1);
quickSort(q, i, r);
}
边界问题:
这里分界点不能选为l,即val不可以等于q[l]
以q=[1,2]为例,val为1:
i变为0,j变为0,后面一直在quickSort(q, 0, 1)