785.快速排序
算法原理:
主要思想:分治
1.确定分界点:q[l] q[(1+r)/I] q[r] 随机
2.调整范围:所有小于等于x在左边,大于等于x在右边(常考且最难)
3.递归处理左右两段
题目:
给定你一个长度为 n 的整数数列。
请你使用快速排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n。
第二行包含 n 个整数(所有整数均在 1∼109 范围内),表示整个数列。
输出格式
输出共一行,包含 n 个整数,表示排好序的数列。
数据范围
1≤n≤100000
输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5
y总给的板子:
#include<iostream>
using namespace std;
const int N = 1e6+10;
int n;
int q[N];
void quick_sort(int q[], int l, int r)
{
if(l >= r)return;//判边界—没有输入或只有一个输入的话直接return
int x = q[l], i = l - 1, j = r + 1;//取分界点x,ij是左右两个指针
while(i<j)//迭代-每次交换算一次迭代
{
do i ++ ; while(q[i] < x);
do j -- ; while(q[j] > x);
if(i < j) swap(q[i],q[j]);//swap是交换两个数
/*手写swap
{
int t = q[i];
q[i] = q[j];
q[j] = t;
}
*/
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);//也可以写i,不过要改x=q[l],不能上取整,会出现边界问题
}
int main()
{
scanf("%d", &n);
for(int i = 0; i < n; i ++ ) scanf("%d", &q[i]);
quick_sort(q, 0, n - 1);
for(int i = 0; i < n; i ++ ) printf("%d", q[i]);
return 0;
}
跑出来的结果会是Time Limit Exceeded我也不知道为什么🤷♀️,也许因为数据加强会报错?!
然后正确答案是:
#include<iostream>
using namespace std;
const int N = 1e6+10;
int n;
int q[N];
void quick_sort(int q[], int l, int r)
{
if(l >= r) return;
int x = q[l + r >> 1];
int i = l - 1;
int j = r + 1;
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);
}
int main()
{
scanf("%d",&n);
for(int i = 0; i < n; i ++) scanf("%d",&q[i]);
quick_sort(q, 0, n - 1);
for(int i = 0; i < n; i ++) printf("%d ",q[i]);
return 0;
}
其实就只把第10行的int x = q[l];改成了int x = q[l + r >> 1];
评论区有位大佬说是位运算,相当于➗2