九、基数排序( RedixSort )总结
作为一种不基于比较而基于数字的排序,基数排序由桶排序发展而来
1.算法原理:
因为桶排序的速度会因为值域的扩大而劣化,所以我们按位考虑,
把所有数根据最高位分桶然后桶内排序。
例如,对于数组 11,12,15,23,31,22
我们按十位可以分成三个桶
1 : 11,12,15
2 : 22,23
3 : 31
这样他们十位就是有序的了,再考虑个位,就会发现不行,原来十位的限制就被打破了,而十位的权重大于个位,所以我们反过来考虑,先按个位分桶排序,然后再按十位排序,然后再更高位,由于桶内部不会破坏原来的顺序,这样,我们就可以轻松排序了,时间复杂度为O( n * C ),C为层数,由于C = log10V,所以理论复杂度并没有比分治的排序优秀,所以我们可以考虑优化,以10为底对于Int32 2e9 的值域来说太过于浪费了.我们考虑以65536为底,则只需要两层即可完成排序,代码如下
2.算法实现及优化
65536为底的基数排序


具体实现理解需要些基础的数据处理功底.而除非当面讲,我也难以讲清楚.所以大家多自己研究吧.
优化:缓存优化
由某著名Oier 王逸松 提出,当 Redix = 255 时,该数组能完美装入缓存,则可以极大的优化速度
虽然 256 ^ 4 才能覆盖In32的值域,但是由于缓存的OI速度超过为内存的10倍,所以在卡常数的时候有奇效
有兴趣的同学可以自己验证一下
3.算法分析
时间复杂度: V很小时 近似O(n)
时间常数: 小
空间复杂度 O(n) + O(n)
优势: 时间复杂度低
劣势: 只能运用于整数
4.算法运用
主要运用于空间不敏感但时间复杂度要求高的场合
不易于比较的多关键字排序
衍生运用1: 后缀排序
例题:
https://www.luogu.org/problemnew/show/P3809题意: 给定字符串S,求所有后缀的排名
倍增以后题目就简化为双关键字的排序,时间复杂度要求高,所以使用基数排序降至O( n*log2n )
衍生运用2: 后缀自动机
例题:
https://www.luogu.org/problemnew/show/P3804由于需要对子串的出现次数排序,而时间复杂度要求O(n),所以使用基数排序解决.
P.S.写的好累啊.为什么没有人捧场呢?
