基本思想:
根据各个数中,各位上的值,通过对待排序数组进行若干次“存入数”和“取出数”来实现排序。
是典型的分配类排序(还包括:计数排序,桶排序等)。
过程:
图示:
简单来说就是对每个数的每个位上的数进行比较并排序,执行最高位数次存入,取出。
代码实现:
import java.util.Arrays;
public class RadixSorting {
public static void main(String[] args) {
int[] a={10,2,3,100,1111,-10};
Sort(a);
System.out.println(Arrays.toString(a));
}
private static void Sort(int[] s){
int max=Integer.MAX_VALUE;//int数据类型的最大取值数:2 147 483 647
int min=Integer.MIN_VALUE;//int数据类型的最小取值数:-2 147 483 648
//求最大数和最小数
for (int i=0;i<s.length;i++){
max=Math.max(min,s[i]);//返回最大值
min=Math.min(max,s[i]);//返回最小值
}
//如果最小数是负数
if(min<0){
for (int i=0;i<s.length;i++){
s[i]=s[i]-min;//减去最小负数,使每个数大于等于0
}
max=max-min;
}
int Maxlength=(max+"").length();//将数字max转化为字符串,调用字符串长度函数length,求最大数最大位数
int[][] song1=new int[10][s.length];//建立一个二维数组,一维表示0-9,二维表示数组长度,用来存储排序的数字
int[] song2=new int[10];//建立一个一维数组,表示0-9数字的个数
//开始排序
for (int i=0,k=1;i<Maxlength;i++,k=k*10){//按照个位,十位,千位.....遍历下去
//存入数
for (int j=0;j<s.length;j++){//每个数都要比较
int temp=s[j]/k%10;//得到第k位上的数
song1[temp][song2[temp]]=s[j];
song2[temp]++;//该位,数的个数加一,为下个要存入的数字确定二维下标
}
//取出数(从左(0)到右(9),从下(0)到上(9)取出)--升序
int tem=0;
for (int t=0;t<song2.length;t++){
if(song2[t]!=0){//判断该位数是否有数字
for (int j=0;j<song2[t];j++){
s[tem]=song1[t][j];
tem++;
}
}
song2[t]=0;//清空个数
}
//取出数(从右(9)边到左(0),从下到上取出)--降序
/*int tem=0;
for (int t=song2.length-1;t>0;t--){
if(song2[t]!=0){//判断该位,是否有数字
for (int j=0;j<song2[t];j++){
s[tem]=song1[t][j];
tem++;
}
}
song2[t]=0;//清空个数
}*/
}
//如果最小数是负数
if (min<0){
for(int i=0;i<s.length;i++){
s[i]=s[i]+min;//加上之前减去的min得到原来的数字
}
}
}
}
结果:
时间复杂度: n为一次“存入”,“取出”的时间复杂度,k(最高位)为要进行多少次“存入”,“取出”。
空间复杂度:n为排序数的个数,k为最高位。
算法特点:
(1):稳定排序。
(2):时间复杂度可以达到O(n)。