基数排序(RadixSort)
1. 理论知识:
1.1 原理:
定义0-9 十个桶 (数组),先排序个位,再排序十位,排序百位...
1.2 例子:
①根据最大值确定需要执行多少遍(这里最大值是三位数,所以执行三遍)
②排序个位
首先,遍历数组把数据放入桶中
然后,按照先后顺序取出数据(先从0号桶取数据,取完再下一号桶)
0号桶取出示例:
一轮结束后:
③排序十位
遍历数组放入数据
取出数据
④排序百位
遍历数组放入数据
取出数据
至此,排序已完成,得到的数组为排好序的数组。
1.3 时间复杂度
在上述例子里,
排序个位: O(n)
排序十位: O(n)
排序百位: O(n)
故: O(kn)
2. 代码
这里,桶定义为二维数组(十个桶十列,每个桶的长度定义为待排序数组长度<防止出现都到一个桶,长度不够的情况>)
定义一个桶记录工具,以确定把数据放入哪个位置,以及取出时方便(为0时代表都取完了,进行下一个桶)
例:当桶记录工具那个桶数为0时(桶中没有数据),可以把数据放入0号位置,数加1,桶中有一个数据,下一次再来一个数据,放入1号位置。
public class RadixSort {
public static void main(String[] args) {
int[] arr= {50,17,41,20,101,35,11,62,25,45,21,45,54,89};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
//取最大值计算最大值的位数
int max=arr[0];
for(int j=0;j<arr.length;j++) {
if(arr[j]>max) {
max=arr[j];
}
}
//最大值的位数
int maxLen = (max+"").length();
//定义桶
int[][] bucket = new int[10][arr.length];
//定义桶记录工具
int[] elementCounts= new int[10];
int n=1;
//放入取出执行maxLen遍
for(int m=0;m<maxLen;m++) {
//遍历数组,将数组中的数据放入桶中
for(int i=0;i<arr.length;i++) {
//element代表个位数值,也代表要放入哪个桶
int element = arr[i]/n%10;
//读取桶记录中的数值
int count = elementCounts[element];
//数据放入
bucket[element][count]=arr[i];
//桶记录中的数据加1
elementCounts[element]++;
}
//将桶中的数据取出
int index=0;//定义index游标,遍历待排序数组
for(int k=0; k<elementCounts.length;k++) {
if(elementCounts[k]!=0) {
//桶中有数据,将数据取出
for(int l=0;l<elementCounts[k];l++) {
arr[index] = bucket[k][l];
index++;
}
}
//清空桶记录
elementCounts[k]=0;
}
n=n*10;
}
}
}