- 基数排序
原理:基数排序是一种“分配式排序”,又称桶排序,即通过将所有数据元素分配到应在的位置最后再覆盖到原数组完成排序。
该排序算法就是按照个十百千万这样进行分配,每一次都排一位,按照数组中最大长度数的位数作为次数进行比较。
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;
//把当前遍历的数据放入指定的数组中,ys为0-9,counts[ys]即是第ys个数组
temp[ys][counts[ys]] = arr[j];
//记录数量,每次存入之后,就是多了一个,下标要+1
counts[ys]++;
}
if(i==0) {
for(int[] nums:temp) {
System.out.println(Arrays.toString(nums));
}
System.out.println(Arrays.toString(counts));
}
//记录取得元素需要放的位置
int index = 0;
//把数字取出来
for(int k=0;k<counts.length;k++) {
//记录 数量的数组 中当前余数记录的数量不为0
if(counts[k]!=0) {
for(int l=0;l<counts[k];l++) {
//遍历取出元素,k为余数数组的序号,l为数量数组的序号
arr[index] = temp[k][l];
//记录下一个位置
index++;
}
//把数量置空,即置为0,下一次要从0开始
counts[k] = 0;
}
}
}
}
- 队列优化型基数排序
我们发现每次存取数组都是先进先出类似于队列,所以可以将上面算法中的数组改为队列。
面向对象的队列:
public class MyQueue {
int[] elements;
public MyQueue() {
elements = new int[0];
}
//入队
public void add(int element) {
int[] newArr = new int[elements.length+1];
for(int i = 0; i < elements.length; i++) {
newArr[i] = elements[i];
}
newArr[elements.length] = element;
elements = newArr;
}
//出队
public int poll() {
//把第0个取出
int element = elements[0];
int[] newArr = new int[elements.length-1];
for(int i = 0;i<newArr.length;i++) {
newArr[i] = elements[i+1];
}
elements = newArr;
return element;
}
//判断为空
public boolean isEmpty() {
return elements.length == 0;
}
}
队列型基数排序:
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();
}
//根据最大长度的数决定比较的次数
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].add(arr[j]);
}
//记录取得元素需要放的位置
int index = 0;
//把所有队列中的数字取出来
for(int k=0;k<temp.length;k++) {
//当前遍历的队列不为空,循环取出元素
while(!temp[k].isEmpty()){
//取出元素
arr[index] = temp[k].poll();
//记录下一个位置
index++;
}
}
}
}