785. 快速排序
题目链接https://www.acwing.com/problem/content/787/
题目:
我: 不知道为什么我写的kp()过不去,但quick()可以过???
y总 :当给定的序列有序时,如果每次选择区间左端点进行划分,每次会将区间[L, R]划分成[L, L]和[L + 1, R],那么相当于每次递归右半部分的区间长度只会减少1,所以就需要递归 n−1n−1次了,时间复杂度会达到 n2n2。但每次选择区间中点或者随机值时,划分的两个子区间长度会比较均匀,那么期望只会递归 lognlogn层。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
void kp(int a[],int l,int r){
if(l>=r)
return ;
int t=a[l];
int i=l,j=r;
while(i<j){
while(i<j&&t<=a[j]) j--;
if(i<j) a[i++]=a[j];
while(i<j&&t>=a[i]) i++;
if(i<j) a[j--]=a[i];
}
a[i]=t;
kp(a,l,i-1);
kp(a,i+1,r);
}
void quick(int a[],int l,int r){
if(l>=r) return ;
int i=l-1,j=r+1,t=a[l+r>>1];
while(i<j){
do i++; while(a[i]<t);
do j--; while(a[j]>t);
if(i<j){
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
quick(a,l,j);
quick(a,j+1,r);
}
int main(){
int n;
int a[100010];
cin>>n;
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
//kp(a,0,n-1);
quick(a,0,n-1);
for(int i=0;i<n;i++)
printf("%d ",a[i]);
return 0;
}