一、基本思想
将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
(数字统一位数,从数字低位到高位依次进行排序)
二、代码
package com.ws.排序.基数排序;
import java.util.Arrays;
public class RadixSort {
public static void main(String[] args) {
int arr[] ={53,3,542,748,14,214};
System.out.println("##########排序前#########");
System.out.println(Arrays.toString(arr));
System.out.println("##########排序后#########");
pai(arr);
System.out.println("排序后="+Arrays.toString(arr));
}
//基数排序方法
public static void pai(int[] arr){
int e=0;
String[] ee={"个","十","百"};
//1。得到数组中最大的位数
int max=arr[0];//假设第一个数事最大的
for (int i=1;i<arr.length;i++){
if (arr[i]>max){
max=arr[i];
}
}
//2.得到最大数事几位数
int maxLength=(max+"").length();
//3.处理
for (int i=0,n=1;i<maxLength;i++,n*=10) {
//每一轮(针对每个元素对应的位进行处理,个、十、百位依次排序)
//定义一个二维数组,表示10个桶,每个桶就是一个一维数组
//说明
//1.二维数组包含10个一维数组
//2.为了防止在放入数组的时候数据溢出,则每个一维数组(桶),大小定为arr.leng
//3.很明确,基数排序是使用空间换时间的经典算法
int[][] tong = new int[10][arr.length];
//为了记录每个桶中实际存放了多少个数据,要定义一个一维数组记录各个桶每次放入的数据个数
int[] flag = new int[10]; //flag[0]就是0桶的放入数据的个数,同时也有几个桶的意思
//针对每个元素的每一轮对应的位进行排序处理
for (int j = 0; j < arr.length; j++) {
//取出每个元素的每一轮相应的位
// int wei = arr[j] % 10;//取出每个元素的个位
int wei=arr[j]/n%10;
//放入对应的桶
tong[wei][flag[wei]] = arr[j]; //flag[wei] 首先是个数,一维数组,就是相应桶有几个元素,就是第几个位置
flag[wei]++;// 假如是第0个桶的 就是100000000 之后再有的话就是200000000 那么这就表示下一次要放的话,桶里的位置就是2
}
//按照桶的顺序(一维数组的下标依次取出数据,放入原来的数组)
int index = 0;//是个赋值原数组的标志位
//遍历每一个桶,并将桶中的数据,放到原数组
for (int k = 0; k < flag.length; k++) {
//如果桶中有数据,才放入原数组
if (flag[k] != 0) {
//循环该桶 既第k个一维数组,放入
for (int l = 0; l < flag[k]; l++) {
//取出元素,放入到原来数组arr
arr[index++] = tong[k][l];
}
}
//相应的桶要清零,以便下一次的十、百。。。位使用
flag[k] = 0;
}
System.out.println("第" + e + "轮对" + ee[e] + "位的处理arr=" + Arrays.toString(arr));
e++;
}
}
}
##########排序前#########
[53, 3, 542, 748, 14, 214]
##########排序后#########
第0轮对个位的处理arr=[542, 53, 3, 14, 214, 748]
第1轮对十位的处理arr=[3, 14, 214, 542, 748, 53]
第2轮对百位的处理arr=[3, 14, 53, 214, 542, 748]
排序后=[3, 14, 53, 214, 542, 748]
大数据测试
package com.ws.排序.基数排序;
import java.text.SimpleDateFormat;
import java.util.Date;
public class RadixSorts {
public static void main(String[] args) {
System.out.println("########大数据排序80000########");
int[] a=new int[80000];
for (int i=0;i<80000;i++){
a[i]=(int)(Math.random()*8000000);
}
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String data=format.format(date);
System.out.println("排序前时间="+data);
//排序
pai(a);
Date date1=new Date();
String data2=format.format(date1);
System.out.println("排序后的时间="+data2);
}
//基数排序方法
public static void pai(int[] arr){
//1。得到数组中最大的位数
int max=arr[0];//假设第一个数事最大的
for (int i=1;i<arr.length;i++){
if (arr[i]>max){
max=arr[i];
}
}
//2.得到最大数事几位数
int maxLength=(max+"").length();
//3.处理
for (int i=0,n=1;i<maxLength;i++,n*=10) {
//每一轮(针对每个元素对应的位进行处理,个、十、百位依次排序)
//定义一个二维数组,表示10个桶,每个桶就是一个一维数组
//说明
//1.二维数组包含10个一维数组
//2.为了防止在放入数组的时候数据溢出,则每个一维数组(桶),大小定为arr.leng
//3.很明确,基数排序是使用空间换时间的经典算法
int[][] tong = new int[10][arr.length];
//为了记录每个桶中实际存放了多少个数据,要定义一个一维数组记录各个桶每次放入的数据个数
int[] flag = new int[10]; //flag[0]就是0桶的放入数据的个数,同时也有几个桶的意思
//针对每个元素的每一轮对应的位进行排序处理
for (int j = 0; j < arr.length; j++) {
//取出每个元素的每一轮相应的位
// int wei = arr[j] % 10;//取出每个元素的个位
int wei=arr[j]/n%10;
//放入对应的桶
tong[wei][flag[wei]] = arr[j]; //flag[wei] 首先是个数,一维数组,就是相应桶有几个元素,就是第几个位置
flag[wei]++;// 假如是第0个桶的 就是100000000 之后再有的话就是200000000 那么这就表示下一次要放的话,桶里的位置就是2
}
//按照桶的顺序(一维数组的下标依次取出数据,放入原来的数组)
int index = 0;//是个赋值原数组的标志位
//遍历每一个桶,并将桶中的数据,放到原数组
for (int k = 0; k < flag.length; k++) {
//如果桶中有数据,才放入原数组
if (flag[k] != 0) {
//循环该桶 既第k个一维数组,放入
for (int l = 0; l < flag[k]; l++) {
//取出元素,放入到原来数组arr
arr[index++] = tong[k][l];
}
}
//相应的桶要清零,以便下一次的十、百。。。位使用
flag[k] = 0;
}
}
}
}
########大数据排序80000########
排序前时间=2021-03-20 12:07:42
排序后的时间=2021-03-20 12:07:42