排序算法总结

1 篇文章 0 订阅

前言

初赛到了,理一下排序算法

冒泡排序

扫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;
}

不稳定

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值