快速排序
看了y神的快速排序,可是说是非常的优雅而简洁了,显得之前学过的书本上的非常臃肿,而且acwing的oj非常看重时间效率,稍不留神就超时了,还学到一句话叫做边界问题背模板
直接上代码:
#include<iostream>
using namespace std;
const int N = 100010;
int q[N], t;
void QuickSort(int q[], int l, int r){
if(l >= r) return;
int i = l - 1, j = r + 1, x = q[(l + r) / 2];
while (i < j) {
do i++; while (q[i] < x);
do j--; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
QuickSort(q, l, j);
QuickSort(q, j + 1, r);
}
int main() {
scanf("%d", &t);
for (int i = 0; i < t; i++) {
scanf("%d", &q[i]);
}
QuickSort(q, 0, t - 1);
for (int i = 0; i < t; i++) {
printf("%d ", q[i]);
}
return 0;
}
代码短小精悍,但是我自己按自己理解写的代码总是超时,比较之后发现
int i = l - 1, j = r + 1, x = q[l];
中的
x = q[l];
这一行出了问题,因为我之前学的快排总是把第一个元素当做pivot,但是测试用例中如果有已经有序的用例的话,时间复杂度就会变成n方,所以要用
x = q[(l + r) / 2];
或者
x = q[(l + r) >> 1];
位运算符相当于向下取整,如果以i为分界点的话就是
x = q[(l + r + 1) >> 1];
新知识点: 数学上可以证明,a/b向上取整,相当于 (a+b-1)/b向下取整,方便代码实现。
完
ps:挑战模式针不戳,帮同学们避免了眼高手低的问题,嘻嘻