基数排序(radix sort),又称桶排序(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用。如先按个位排,再将元素按十位排,再将元素按百位排…直到达到最高位。基数排序法是属于稳定性的排序,其时间复杂度为O (nlog®m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。
//桶排序
public static void radixSort(int[]arr) {
//存取数组中最大的数字
int max=Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
if(arr[i]>max){
max=arr[i];
}
}
//计算最大数字是几位数
int maxLength=(max+"").length();
//用于临时存储数据的数组
int[][]temp=new int[10][arr.length];
//用于记录在temp中相应的数组中存放的数字数量
int[]counts=new int[10];
//根据最大长度的数决定比较的次数
for (int i = 0,n=1; i < maxLength; i++,n*=10) {
//把每一个数字分别计算余数
for (int j = 0; j < arr.length; j++) {
//计算余数
int ys=arr[j]/n%10;
//把当前遍历的数据放入指定的数组中
temp[ys][counts[ys]]=arr[j];
//记录数量
counts[ys]++;
}
//记录取的元素需要放的位置
int index=0;
//把数字取出来
for (int k = 0;k <counts.length; k++){
//记录数量的数组中当前余数记录的数量不为0
if(counts[k]!=0){
//循环取出元素
for (int l = 0; l <counts[k]; l++) {
//取出元素
arr[index]=temp[k][l];
//记录下一个位置
index++;
}
//把数量置为0
counts[k]=0;
}
}
}
}
import java.util.Arrays;
//测试类
class RadixSort{
public static void main(String[] args) {
int[]arr=new int[]{23,6,189,45,9,287,56,1,798,34,65,652,5};
radixSort(arr);
//输出[1, 5, 6, 9, 23, 34, 45, 56, 65, 189, 287, 652, 798]
System.out.println(Arrays.toString(arr));
}
由于桶排序原理上每次按位排序元素都遵循先进先出的规则,这里也可以使用队列实现桶排序。
//使用队列实现桶排序
public static void radixQueueSort(int[]arr) {
//存取数组中最大的数字
int max=Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
if(arr[i]>max){
max=arr[i];
}
}
//计算最大数字是几位数
int maxLength=(max+"").length();
//用于临时存储数据的队列
MyQueue[]temp=new MyQueue[10];
//为队列数组赋值
for (int i = 0; i < temp.length; i++) {
temp[i]=new MyQueue();
}
//用于记录在temp中相应的数组中存放的数字数量
int[]counts=new int[10];
//根据最大长度的数决定比较的次数
for (int i = 0,n=1; i < maxLength; i++,n*=10) {
//把每一个数字分别计算余数
for (int j = 0; j < arr.length; j++) {
//计算余数
int ys=arr[j]/n%10;
//把当前遍历的数据放入指定的队列中
temp[ys].enQueue(arr[j]);
}
//记录取的元素需要放的位置
int index=0;
//把所有队列中的数字取出来
for (int k = 0;k <temp.length; k++){
//当前遍历的队列不为空,循环取出元素
while(!temp[k].isEmpty()){
//取出元素
arr[index]=temp[k].deQueue();
//记录下一个位置
index++;
}
}
}
}