基数排序模板(基数排序,C++模板)
算法的理论学习可右转Creeper_LKF大佬的洛谷日报
一个优化算法理论时间复杂度的实例点这里
另一个实例点这里
时间复杂度,算常数的话要乘位长。
蒟蒻参考了Creeper_LKF大佬的模板,并在通用性上面稍微提升了一点。可以兼容所有存储整数的基本类型,以及在此基础上构建的结构体类型(多关键字排序时,优先级高的关键字默认需要在结构体中靠后)。
函数原型
template<typename T>
void Radixsort(T*fst,T*lst,T*buf,int*op)
T
即为待排序的类型名,fst
lst
为首尾指针(和sort
一样),buf
为缓冲区指针,op
为操作列表。
提供类型的第个字节的比较方式,具体来说有种取值。
:该字节不是排序的关键字。
:以该字节为基准从小到大排序。
:以该字节为基准从大到小排序。
:以该字节为基准从小到大排序,且该字节的最高位是有符号整形的符号位。
:以该字节为基准从大到小排序,且该字节的最高位是有符号整形的符号位。
例如,对int
从小到大排序,则应将传入。
对结构体unsigned int,int
以前一个为关键字从大到小排序,则代码大致写成
Radixsort(a,a+n,buf,new int[8]{1,1,1,1,-1,-1,-1,-1});
对长度为的int
数组排序效率对比如下:(STL不吸氧是真的布星)
然而,Radixsort
的运行时间与待排序类型的关键字位长总和成正比(upd:蒟蒻目测和总位长也有关,猜测是因为访问步长增加导致缓存刷新次数增加。例如,对long long
排序大约是对int
排序的三倍时间)。
而std::sort
受此的影响小多了。当总位长在位以上时,开O2以后两者的差距很小了。所以综合实现难度方面,int
多关键字和long long
等用开O2的std::sort
就够了。
至于实数类型,Radixsort
不能直接资磁。double
是位的用std::sort
就好了。至于如果是在想从小到大排float
的话,必须膜改一下数组,将所有的负实数强行除了符号位都按位取反以后,传入,最后还要还原回来,实在是太麻烦了。
#include<bits/stdc++.h>
#define UC unsigned char
using namespace std;
template<typename T>
void Radixsort(T*fst,T*lst,T*buf,int*op){
static int b[0x100];
int Len=lst-fst,Sz=sizeof(T),at=0,i,j;
UC*bgn,*end,tmp;
for(i=0;i<Sz;++i){
if(op[i]==-1)continue;
bgn=(UC*)fst+i;end=(UC*)lst+i;
tmp=((op[i]&1)?0xff:0)^((op[i]&2)?0x80:0);
memset(b,0,sizeof(b));
for(UC*it=bgn;it!=end;it+=Sz)++b[tmp^*it];
for(j=1;j<0x100;++j)b[j]+=b[j-1];
for(UC*it=end;it!=bgn;buf[--b[tmp^*(it-=Sz)]]=*--lst);
lst=buf+Len;swap(fst,buf);at^=1;
}
if(at)memcpy(buf,fst,Sz*Len);
}
有没有觉得很好实现呢?比什么后缀排序不知道好写到哪里去了
这样实现很简短,但常数没有卡到极限,b桶数组的初始化部分可以强行展开出来并行计算。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具