1.基本思想
基数排序是通过“分配”和“收集”过程来实现排序
2.实现原理
基数排序(以整形为例),将整形10进制按每位拆分,然后从低位到高位依次比较各个位。主要分为两个过程:
(1)分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中(比如53,个位为3,则放入3号桶中)
(2)收集,再将放置在0~9号桶中的数据按顺序放到数组中
重复(1)(2)过程,从个位到最高位(比如32位无符号整形最大数4294967296,最高位10位)
3.代码实例
(1)代码:
//pos=1表示个位,pos=2表示十位 public static int getNumInPos(int num, int pos) { int tmp = 1; for (int i = 0; i < pos - 1; i++) { tmp *= 10; } return (num / tmp) % 10; } //求得最大位数d public static int getMaxWeishu(int[] a) { int max = a[0]; for (int i = 0; i < a.length; i++) { if (a[i] > max) max = a[i]; } int tmp = 1, d = 1; while (true) { tmp *= 10; if (max / tmp != 0) { d++; } else break; } return d; } public static void radixSort(int[] a, int d) { int[][] array = new int[10][a.length + 1]; for (int i = 0; i < 10; i++) { array[i][0] = 0;// array[i][0]记录第i行数据的个数 } for (int pos = 1; pos <= d; pos++) { for (int i = 0; i < a.length; i++) {// 分配过程 int row = getNumInPos(a[i], pos); int col = ++array[row][0]; array[row][col] = a[i]; } for (int row = 0, i = 0; row < 10; row++) {// 收集过程 for (int col = 1; col <= array[row][0]; col++) { a[i++] = array[row][col]; } array[row][0] = 0;// 复位,下一个pos时还需使用 } } } public static void main(String[] args) { int[] a = { 49, 38, 65, 197, 76, 213, 27, 50 }; radixSort(a, getMaxWeishu(a)); for (int i : a) System.out.print(i + " "); }
(2)结果:
27 38 49 50 65 76 197 213
4.算法分析
该算法所花的时间基本是在把元素分配到桶里和把元素从桶里串起来;把元素分配到桶里:循环 length 次;
把元素从桶里串起来:这个计算有点麻烦,看似两个循环,其实第二循环是根据桶里面的元素而定的,可以表示为:k×buckerCount;其中 k 表示某个桶中的元素个数,buckerCount 则表示存放元素的桶个数;
有几种特殊情况:
第一、所有的元素都存放在一个桶内:k = length,buckerCount = 1;
第二、所有的元素平均分配到每个桶中:k = length/ bukerCount,buckerCount = 10;(这里已经固定了10个桶)
所以平均情况下收集部分所花的时间为:length (也就是元素长度 n)
综上所述:
时间复杂度为:posCount * (length + length) ;其中 posCount 为数组中最大元素的最高位数;简化下得:O( k*n ) ;其中k为常数,n为元素个数;
该算法的空间复杂度就是在分配元素时,使用的桶空间;所以空间复杂度为:O(10 × length)= O(length)