基数排序
一、定义
基数排序是桶排序的一个方案。基数排序有时候也叫卡片排序。既然基数是桶排序的一种实现,我们需要先稍微了解下桶排序。
桶排序
概念上,假设当出现一个数组,\(A_1,A_2,A_3,…,A_N\)必须是小于\(M\)的正整数组成。那么对这个数组进行桶排序:
- 选择一个大小为M的count数组,初始化全为0。
- 当读入\(A_i\)时,\(count[A_i]\)增1。
- 所有的数据被读入之后,扫描count,打印出排序的表。
- 该算法用时\(O(M+N)\)。
M即为输入数组的桶的数组。桶排序,这里看上去似乎还是很抽象,那么再看一个具体的实现,也就是基数排序,两者概念、做法相互印证。大概能理解他们的意思。
基数排序
假设我们有数组中含有10个元素,它的每个元素都是小0~999的数字。设数组a=[64,8,216,512,27,729,2,1,343,125]。我们对数组a进行基数排序,此处叫基数排序而不是桶排序,因为如果用桶排序,那么桶的个数将会至少是1000,那是不能接受的。我们的做法是:
- 构造10个桶,分别标记为0~9。
- 对数字分别进行排序,首先对个位进行排序。
- 再对十位进行排序。
- 最后对百位进行排序。
- 结论:最后得到的数组就是有序的。
图解
图解说明
- 先构建大小为10的桶数组
- 对个位进行排序,排序方式是:将各位为0的放入0号同,个位为1的放入1号桶,个位为\(i\)的放入\(i\)号桶。
- 再对十位排序,排序方式同上。
- 最后对百位排序。
二、算法分析
算法分析简单得很,对上述过程进行分析,很明显:
我们需要进行个位、十位、百位三趟排序。而且每趟都要对所有的数字进行排序。所以我们的算法是总个数N*趟数L。其表述为\(O(NL)\),L的大小根桶的选择方式有关系。但是算法还是线性的。
三、代码实现
代码实现中提供了两种排序方式,一种是基数排序,另一种是基数排序的另一种实现,叫做计数基数排序。原理一样,但是做法略有不同。它采用的是在桶中计数,而不是直接存入值的方式。
https://github.com/dhcao/dataStructuresAndAlgorithm/blob/master/src/chapterSeven/RadixSortEx.java
凡你能说的,你说清楚。凡你不能说的,留给沉默!