思想
类似于桶排序,按照某种规则将相同规则的数放在一起,最后使得序列有序。基数排序是按照数字每位数出现的数字进行排序,每位数出现的数字可能是:0、1、2、3、4、5、6、7、8、9,按照这10个数分到不同的桶中,第一次按照个位数分桶,第二次按照十位数分桶,第三次按照百位数分桶,…,最后按照最高分为分桶,这样最后的数组就是有序的。
例子
例子说的很明白
算法
求数字num第pos位上的数
/**
* 获取基数
* @param num
* @param pos
* @return
*/
public int getRadix(int num,int pos){
int tmp = 1;
for(int i=0;i<pos-1;i++)
tmp*=10;
return (num/tmp)%10;
}
基数排序
public void radixSort(int[] A){
int n = A.length;
int[][] B = new int[10][n]; // 10个桶
int[] order = new int[10]; // 记录每个桶内的数的个数
int pos = 1;// 从个位开始遍历
int radix = 0;//基数,桶号
int num;
boolean flag = true;
while(flag){
B = new int[10][n]; // 每次初始10个桶
order = new int[10]; // 每次初始每个桶内的数的个数
for(int i=0;i<n;i++){ // 遍历所有元素
num = A[i];
radix = getRadix(num,pos); // 求出基数,或者说桶号
B[radix][order[radix]] = num;
order[radix]++;
// 数据都放在一个桶内,结束
if(order[radix]==n){
flag=false;
}
}
if(flag)// 更新数组
updateA(A,B,order);
pos++;
}
}
利用桶信息更新序列
/**
* 利用桶更新序列
* @param A 原始数组
* @param B 桶
* @param order 每个桶有效数据个数
*/
public void updateA(int[]A,int[][] B,int[] order){
int i=0;
for(int r=0;r<=9;r++){
if(order[r]==0)
continue;
for(int j=0;j<order[r];j++){
A[i++] = B[r][j];
}
}
}
主函数
public static void main(String[] args){
int[] A = new int[]{49,38,65,97,76,13,27,49};
Print.printArray(A);
RadixSort radixSort = new RadixSort();
radixSort.radixSort(A);
Print.printArray(A);
}
输出
49 38 65 97 76 13 27 49
13 27 38 49 49 65 76 97
复杂度分析
(1)时间复杂度
无论什么情况都需要对特定的位遍历所有元素
时间复杂度
O(dn)
d:最高位数
n:数据数量
(2)空间复杂度
桶的数量*元素个数=
O(10n)
基数排序也可以对其中字符进行排序,如字母组成的字符串,操作类似