基数排序(radix sort)基本介绍(直接略过吧!!)
基数排序基本思想(直接略过吧 !!!)
将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
具体实现为(这才是重点)
定义十个桶,分别代表为数字0-9;依次取所有数值的个位,对应进入到0-9十个桶,全部进入桶后,再从桶中按桶的顺序将数值还原到数组中(这个顺序为将0号桶的数据按下标顺序还原->将1号桶的数据按下标顺序还原->…->将9号桶的数据按下标还原);接着依次取每个数值的十位数,重复上述操作;接着去百位、千位。。。直到绝对值最大的那个数的所有位数被取完,最终达到排序目的。
注意:
1.进入桶再还原到数组的过程的次数等于数组中绝对值最大的那个数的位数
2.桶是一个10 * nums.length的二维数组,因此技术排序需要额外(10*数组长度)大小的空间,空间复杂度为O(10*n),数据量太大时可能出现OOM。
如果没有明白就看看下面的栗子吧
要排序的数组 | 542 | 36 | 2 | 178 | 71 | 89 | 6 | 18 | 188 | 66 |
---|
第1趟:按个位数进入对应的桶
桶序号 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
542 | 36 | 71 | 178 | 89 | ||||||
2 | 6 | 18 | ||||||||
66 | 188 |
将桶中的数据按顺序还原到原数组,这时位数为1的数已经有序了
第1趟入桶后 | 542 | 2 | 36 | 6 | 66 | 71 | 178 | 18 | 188 | 89 |
---|
第2趟:按十位数进入对应的桶,没有补0
桶序号 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
2 | 18 | 36 | 542 | 66 | 71 | 188 | ||||
6 | 178 | 89 |
将桶中的数据按顺序还原到原数组,这时所有两位数也有序了
第2趟入桶后 | 2 | 6 | 18 | 36 | 542 | 66 | 71 | 178 | 188 | 89 |
---|
第3趟:按百位数进入对应的桶,没有补0
桶序号 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
2 | 178 | 542 | ||||||||
6 | 188 | |||||||||
18 | ||||||||||
36 | ||||||||||
66 | ||||||||||
71 | ||||||||||
89 |
将桶中的数据按顺序还原到原数组,这时所有的三位数也有序了,整体也排序完毕了
第3趟:排序完成 | 2 | 6 | 18 | 36 | 66 | 71 | 89 | 178 | 188 | 542 |
---|
进入桶的趟数与数组中绝对值最大的那个数的位数有关,比如最大的数为123456,那么就要进入桶6趟,而这里最大的数为542,有3位,所以流程会进行3趟。
代码实现
/**
* @author chenzhiyuan
* @date 2019-09-06 17:44
*/
public class RadixSort {
public static void main(String[] args) {
int[] nums = new int[]{
-10, 2, 11, 0, 20, 8, 90, 22, 1