倍增排序

这种排序叫倍增排序,用于对正整数排序,负整数的话可以先都加上一个大的正数再用这种排序,它是基于寻址来排序的,不像快排是基于比较的,倍增排序的速度 比快速排序快,是稳定的,不会退化到O(n^2),其时间复杂度为O(n+sqrt(m))(此处m指这些正整数的最大值,用dword类型时取 2^32-1,n指待排序数的个数),空间 复杂度也是一样,怎么样?是不是比O(n*Logn)快?它的原理和计数排序相似,但排序用的指标不同,它是用a和sqrt(m)的余数、商作为指标,为了加快运行速度,用位运算计算商和余数。
一下是pascal源代码:
const
max=65535;//这边的max就相当于sqrt(m),max一定要(11....11)形式的二进制数,这样才可以用and来求余,提高速度。
var
i,n:longint;
a,b:array[1..1000000]of longint;
m,d:array[0..max+1]of longint;
begin
readln(n);
for i:=1 to n do
begin
read(a[ i]);
inc(m[1+a[ i] and max]);//此时的m表示余数a[ i] mod (max+1)为的数有几个,a[ i] and max=a[ i] mod (max+1)
inc(d[1+a[ i] shr 16]);//此时的d表示商为a[ i] div (max+1)的数有几个,a[ i] shr 16=a[ i] div (max+1)
end;
for i:=1 to max+1 do
begin
inc(m[ i],m[i-1]);//此时的m表示余数小于i(因为前面有加1,所以这里是小于)的数字的个数
inc(d[ i],d[i-1]);//此时的d表示商小于i(因为前面有加1,所以这里是小于)的数字的个数
end;
for i:=1 to n do//这边是按照余数排序
begin
inc(m[a[ i] and max]);//设t=a[ i]and max,这里表示余数为t的数应该放在的地址,因为前面累加之后,m[ t]已经表示余数小于t的数字有多少个,所以当有数字的余数为t时,应从t+1个位置开始放置在b数组,inc(m[ t])表示放置第几个余数为t的数字的地址。
b[m[a[ i] and max]]:=a[ i];
end;
for i:=1 to n do//这边基于已经按照余数排好序的数据再按照商排序
begin
inc(d[b[ i] shr 16]);//设t=a[ i]shr 16,这里表示商为t的数应该放在的地址,因为前面累加之后,d[t]已经表示商小于t的数字有多少个,所以当有数字的商为t时,应从t+1个位置开始放 置在a数组,inc(m[ t])表示放置第几个商为t的数字的地址。
a[d[b[ i] shr 16]]:=b[ i];
end;
for i:=1 to n-1 do write(a[ i],' ');
write(a[n]);
end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值