基数排序法

Posted 算法精解

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基数排序法相关的知识,希望对你有一定的参考价值。

简介

基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。

算法过程

最高位优先(Most Significant Digit first)法,简称MSD 法:

1)先按k1排序分组,将序列分成若干子序列,同一组序列的记录中,关键码k1 相等。

2)再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd 对各子组排序后。

3)再将各组连接起来,便得到一个有序序列。扑克牌按花色、面值排序中介绍的方法一即是MSD 法。

最低位优先(Least Significant Digit first)法,简称LSD 法:

1) 先从kd开始排序,再对kd-1进行排序,依次重复,直到按k1排序分组分成最小的子序列后。

2) 最后将各个子序列连接起来,便可得到一个有序的序列,扑克牌按花色、面值排序中介绍的方法二即是LSD 法。

算法实现

基数排序Golang代码如下。

func RadixSort(arr[] int) { max := arr[0] for i := 1; i < len(arr); i++ { if arr[i] > max { max = arr[i] } }
// 关键字的个数 keysNum := 0 for max > 0 { max /= 10 keysNum++ }
tmp, count := make([]int, len(arr)), make([]int, 10) radix := 1 for i := 0; i < keysNum; i++ { for j := 0; j < 10; j++ { // 每次分配前清空计数器 count[j] = 0 } for j := 0; j < len(arr); j++ { // 统计每个桶中的记录数 k := (arr[j] / radix) % 10 count[k]++ } for j := 1; j < 10; j++ { count[j] = count[j - 1] + count[j] } for j := len(arr) - 1; j >= 0; j-- { // 将所有桶中记录依次收集到tmp中 k := (arr[j] / radix) % 10 tmp[count[k] - 1] = arr[j] count[k]-- } copy(arr, tmp) radix *= 10 }}
测试用例
func TestRadixSort(t *testing.T) { rand.Seed(time.Now().Unix()) var arr []int for i := 0; i < 10; i++ { temp := rand.Intn(1000) arr = append(arr, temp) } originSort, origin := append([]int{}, arr...), append([]int{}, arr...) sort.Ints(originSort) radixSort.RadixSort(arr) if !reflect.DeepEqual(originSort, arr) { t.Errorf("Got %v for input %v; expected %v", arr, origin, originSort) }}

测试结果如图1所示。

图1 测试结果

算法分析

时间复杂度

每一次关键字的桶分配都需要O(n)的时间复杂度,而且分配之后得到新的关键字序列又需要O(n)的时间复杂度。

假如待排数据可以分为d个关键字,则基数排序的时间复杂度将是O(d*2n) ,当然d要远远小于n,因此基本上还是线性级别的。

系数2可以省略,且无论数组是否有序,都需要从个位排到最大位数,所以时间复杂度始终为O(d*n) 。其中,n是数组长度,d是最大位数

空间复杂度

  基数排序的空间复杂度为O(n+k),其中k为桶的数量,需要分配n个数。

以上是关于基数排序法的主要内容,如果未能解决你的问题,请参考以下文章

基础排序算法总结(代码+图片分析)

排序-基数排序

基数排序法

java方式实现基数排序

归并排序法和基数排序法

重温基础算法内部排序之基数排序法