基数排序是一种复杂度为n * max(每个数的位数)的优秀算法,平常用的不多,但求后缀数组的时候为了达到nlogn的复杂度一般都会采用基数排序,因此还是很有必要学一下的。
大概的意思就是说,对于一个数列而言,我们先以个位数为权值桶排一遍得到一个新的排列,然后再在这个排列的基础上以十位数为权值桶排一遍得到一个新的排列,再在这个排列的基础上以百位数为权值桶排一遍得到一个新的排列……最后以所有数中的最大位数为权值桶排一遍得到一个新的序列,这个最后得到的新序列就是已经拍好序的了。
举个例子:
我们现在有12 23 39 15四个数,我们先以个位数为权值桶排一遍 ,得到新序列12 23 15 39.
然后再以十位数为权值桶排一遍,这个时候会发现1号桶中出现了2个数,分别是12和15,然后观察到在第一次排序得到的序列中,12在前面,因此我们给12的排名定为1,15的排名定为2.
于是我们就得到了最后的序列12 15 24 39.
因为后面的排序虽然会打乱上一次的排序结果,但打乱它的原因是有些数的当前位不相同。又因为对于任意一个数而言,它的当前位大,那么不管它之前的位有多小,它都比别人大。
例如:9000 > 1999,因为9000的千位比1999大,所以即使它的个、十、百位都比1999小,它仍然比1999大。
对于当前位相同的数,我们是不会改变它们的相对位置的,例如上一次排序的结果(局部)是123,146,157,那么因为它们的当前位(百位)都为1,我们不会改变这几个数的排列,所以就保证了整体的有序。
如果仍有疑问,不妨看看这个例子:
假如我们上一次得到的排序结果是: 12 23 14 37 18.
那么正确的序列显然是12 14 18 23 37.
那么我们怎么在已经根据个位排好序的情况下再根据十位排出正确的序列呢?
首先因为是桶排,1号桶中会存放14 12 18这几个数,2号桶中会存23,3号桶中存37.
然后我们依次从1,2,3号桶中取数。
1号桶中有3个元素,我们按照上一次排序的顺序依次取出得到12 14 18,对于后面的桶都只有一个元素,直接取出即可。
于是我们就得到了12 14 18 23 37这个序列