基数排序属于“分配式排序”,又称“桶子法”;
时间复杂度是 O(nlog(r)m),r为所采取的基数,m为桶数;
是一种稳定的排序算法;
空间效率:需要额外的空间,典型的空间换时间的算法;
算法步骤:
第一步:循环每一个基;
第二步:循环内部以一个基为依据,遍历待排序的数据集,将元素放入对应的桶中;
第三步:遍历桶,将元素返回到待排序的数据集中。
说明:
基 => 被排序的元素的个位,十位,百位 ... 叫基
桶 => 基的每一位的取值范围
具体例子:
假如待排序的数据集为 : int[] nums = new int[]{72,11,28,32,44,13,38,79,10};
待排序数组muns 有个位和十位两个基数,需要循环两次;
第一次循环,以个位为依据:
第一步:把个位相同的的元素依次放到对应编号的桶bucket中,
桶中元素为:
bucket[0] = 10
bucket[1] = 11
bucket[2] = 72,32
bucket[3] = 13
bucket[4] = 44
bucket[5] =
bucket[6] =
bucket[7] =
bucket[8] = 28,38
bucket[9] = 79
第二步:把桶中的元素依次放入待排序集合nums中,
集合nums为:
nums = {10, 11, 72, 32, 13, 44, 28, 38, 79}
第二次循环,以十位为依据:
第一步:把十位位相同的的元素依次放到对应编号的桶bucket中,
桶中元素为:
bucket[0] =
bucket[1] = 10,11,13
bucket[2] = 28
bucket[3] = 32,38
bucket[4] = 44
bucket[5] =
bucket[6] =
bucket[7] = 72,79
bucket[8] =
bucket[9] =
第二步:把桶中的元素依次放入待排序集合nums中,
集合nums为:
nums = {10, 11, 13, 28, 32, 38, 44, 72, 79}
排序结束,没有一次数据的交换
代码:
/**
* 基数排序
* @author viruser
*
*/
public class RadixSort {
public static int[] sort(int[] nums) {
int[][] bucket = new int[10][nums.length];
int[] order = new int[10]; //数组order[i]用来表示该位是i的数的个数
int maxd = 1; //最大的数有多少位
int m = 1;
int n =1;
int k = 0;
while (m <= maxd) {
for (int i =0; i<nums.length; i++) {
if (m == 1) {
maxd = (nums[i]+"").length() > maxd ? (nums[i]+"").length() : maxd;
}
int index = (nums[i] / n) % 10;
bucket[index][order[index]++] = nums[i];
}
for (int i=0; i<10; i++) {
if (order[i] != 0) {
for (int j=0; j<order[i]; j++) {
nums[k++] = bucket[i][j];
}
order[i] = 0;
}
}
n *= 10;
m++;
k = 0;
}
return nums;
}
public static void main(String[] args) {
int[] nums = new int[]{72,11,2282,32,44,13,17,95,4,28,79,0};
nums = RadixSort.sort(nums);
for (int i =0; i<nums.length; i++) {
System.out.println(nums[i]);
}
}
}