!
最近干了一些有意思的事情:拿出来写一写
关于各种sort!
比如,c++自带的快排,归并排序,还有stdlib库里面的qsort
还有我自己实现的二进制基排,65536进制基数排序,普通归并排序,FFT式归并排序
以及基于队列实现的queue-mergesort(其实本质还是mergesort啦)
目前测试结果来看,表现最好的,应该是普通归并排序(65536基排不算),排序
1
0
7
10^7
107个数字只用了1.1s,让后就是queue-mergesort
反正各种快排没有那么优秀啦,加上O3还是没有mergesort快
解释一下这个queue-mergesort
首先,每个数作为一个独立的“块”放入队列中,每次取出开头的两个“块”进行合并让后丢到队尾,容易看出这个算法复杂度为
O
(
n
log
n
)
O(n\log n)
O(nlogn)
算法本身需要用到循环队列进行辅助操作,让后为了减小常数,取模使用位运算代替,这就意味着要牺牲一部分空间作为代价,同时,为了记录各个块的信息,还要额外开一个数组记录
不过这个算法的思想还是很不错的
放一个code上来
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#define SIZ 10000000
using namespace std;
unsigned s[20000001],b[33554431],*w=s;
inline int mkd(){
for(int T=SIZ;T;--T)
s[T]=(s[T+1]*3859+65492)^235993592ll;
}
int cmp(const void* a,const void* b){
return *(unsigned*)a<*(unsigned*)b?-1:1;
}
inline void radix(int V,int n=10000000){
int c[65536]={0};
for(int i=1;i<=n;++i) ++c[s[i]>>V&65535];
for(int i=1;i<65536;++i) c[i]+=c[i-1];
for(int i=n;i;--i) b[c[s[i]>>V&65535]--]=s[i];
memcpy(s+1,b+1,n<<2);
}
inline void merge(int l,int r){
if(l<r){
register int m=l+r>>1,i=l,j=m+1,t=l;
merge(l,m); merge(m+1,r);
for(;i<=m && j<=r;)
b[t++]=(s[i]<=s[j]?s[i++]:s[j++]);
for(;i<=m;b[t++]=s[i++]);
for(;j<=r;b[t++]=s[j++]);
memcpy(s+l,b+l,r-l+1<<2);
}
}
inline void split(int l,int r,unsigned V){
if(l<r){
int i=l,j=r;
for(;i<j;){
for(;i<j&&s[j]&V;--j);
for(;i<j&&~s[i]&V;++i);
if(i<j) s[i]^=s[j]^=s[i]^=s[j];
else{ s[j]&V?--i:++j; break; }
}
V>1?split(l,i,V>>1),split(j,r,V>>1):(void)0;
}
}
inline void FFT(int n){
int m; for(m=1;m<n;m<<=1);
for(int i=m;i>n;--i) s[i]=-1;
register unsigned *S=s,*B=b;
for(register int L=2,M=1,l,i,j;M<m;L<<=1,M<<=1){
for(l=0;l<m;l+=L,S+=L){
for(i=1,j=M+1;i<=M&&j<=L;)
*++B=(S[i]<=S[j]?S[i++]:S[j++]);
for(;i<=M;*++B=S[i++]);
for(;j<=L;*++B=S[j++]);
}
S-=m; B-=m; swap(S,B);
}
}
inline void chk(){
for(int i=1;i<SIZ;++i)if(s[i]>s[i+1])
puts("#");
puts("Pass");
}
inline void qusort(int n){
const int m=33554431;
register int H=0,T=-1,t=n,l,r,M,i,j;
memcpy(b+1,s+1,n<<2);
for(int i=1;i<=n;++i) w[++T]=i;
for(;H<T;){
l=w[H++]; M=w[H++]; w[++T]=t+1&m; r=w[H];
for(i=l,j=M;(i&m^M)&&(j&m^r);)
b[++t&m]=(b[i&m]<=b[j&m]?b[i++&m]:b[j++&m]);
for(;i&m^M;b[++t&m]=b[i++&m]);
for(;j&m^r;b[++t&m]=b[j++&m]);
}
t=w[T];
for(int i=0;i<n;++i) s[i+1]=b[i+t&m];
}
int main(){
mkd();
qsort(s+1,10000000,4,cmp);
FFT(10000000);
sort(s+1,s+10000001);
stable_sort(s,s+1+10000001);
radix(0); radix(16);
merge(1,10000000);
split(1,10000000,1u<<31);
qusort(SIZ);
chk();
}