前言
初赛到了,理一下排序算法
冒泡排序
扫n遍,每一遍比较相邻大小
复杂度
O
(
n
2
)
\mathcal O(n^2)
O(n2)
稳定
插入排序
每次插入一个数到相应位置
复杂度
O
(
n
2
)
\mathcal O(n^2)
O(n2)
稳定
选择排序
每次选一个最小的加入
复杂度
O
(
n
2
)
\mathcal O(n^2)
O(n2)
尽管我写的是稳定的,但是好像说它不稳定
堆排序
全放堆里,每次取出最小的
复杂度
O
(
n
l
o
g
n
)
\mathcal O(nlogn)
O(nlogn)
堆排序属于选择排序,也不稳定
归并排序
sort(l,r)
{
sort(l,mid),sort(mid+1,r)
lnext=l,rnext=mid+1,p=l
for i=l->r
if lnext<=mid&&(a[lnext]<a[rnext]||rnext>r)
ans[p++]=a[lnext++]
else
ans[p++]=a[rnext++]
memcpy(a,ans)
}
复杂度
O
(
n
l
o
g
n
)
\mathcal O(nlogn)
O(nlogn)
稳定
快速排序
sort(l,r)
{
sort(l,mid),sort(mid+1,r)
v=a[l]
lnext=l,rnext=r
while(lnext<rnext)
while(lnext<rnext&&a[rnext]>v)rnext--;
a[lnext]=a[rnext];
while(lnext<rnext&&a[lnext]<v)lnext++;
a[rnext]=a[lnext];
a[lnext]=v;
}
复杂度
O
(
n
l
o
g
n
)
\mathcal O(nlogn)
O(nlogn)
不稳定
基数排序(桶排序)
放桶里,然后桶的话看情况开
O
(
n
)
\mathcal O(n)
O(n)加点常数
稳定
希尔排序
原理大概是,每次选个步长
d
d
d,然后每隔
d
d
d拿出来,然后整体做一遍插入排序
然后具体复杂度根据步长序列而定,好像能做到挺优的,最一般的最劣是
O
(
n
2
)
\mathcal O(n^2)
O(n2)的
然后具体最优情况的最劣复杂度我也不清楚
详情可以参考https://en.wikipedia.org/wiki/Shellsort
我写了一个常数巨大的希尔排序,用的是3-smoothnumber
但是效果一般,不太星
#include<cstdio>
#include<cctype>
#include<algorithm>
#define rg register
typedef long long ll;
template<typename T>inline void read(T&x)
{
char cu=getchar();x=0;bool fla=0;
while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}
while(isdigit(cu))x=x*10+cu-'0',cu=getchar();;
}
template<typename T>inline void printe(const T x)
{
if(x>=10)printe(x/10);
putchar(x%10+'0');
}
template<typename T>inline void print(const T x)
{
if(x>=0)printe(x);
else putchar('-'),printe(-x);
}
int n,a[100001];
int d[100001],top,ma;
void dfs2(int x)
{
if(x>ma)return;
d[++top]=x;
dfs2(x*3);
}
void dfs1(int x)
{
if(x>ma)return;
dfs2(x);
dfs1(x*2);
}
int p[100001],sum;
int sta[100001];
void st()
{
for(rg int i=top;i>=1;i--)
{
for(rg int bg=1;bg<=d[i];bg++)
{
sum=0;
for(rg int j=bg;j<=n;j+=d[i])sum++;
for(rg int k=1,j=bg;k<=sum;k++,j+=d[i])
{
bool fla=1;
for(rg int l=1;l<k;l++)
if(a[j]<sta[l])
{
for(rg int ppp=k-1;ppp>=l;ppp--)sta[ppp+1]=sta[ppp];
sta[l]=a[j];
fla=0;
break;
}
if(fla)sta[k]=a[j];
}
sum=0;
for(rg int j=bg;j<=n;j+=d[i])a[j]=sta[++sum];
}
}
}
int main()
{
read(n),ma=n/2;
dfs1(1);
std::sort(d+1,d+top+1);
for(rg int i=1;i<=n;i++)read(a[i]);
st();
for(rg int i=1;i<=n;i++)print(a[i]),putchar(' ');
return 0;
}
不稳定