package cn.gs.radixsort;
import java.util.Arrays;
/**
* 基数排序
* 桶排序的扩展
* @author Administrator
* 实现思路:将整数按位数切割成不同的数字,然后按每个位数分别比较
* 出现的小bug:遇到负数会出现索引越界的异常
* 解决方案:1.对负数和正数分开处理,最后进行拼接
* 2.分别加上一个足够大的数,使之都为正数,随后排序,排序结束后,在减去该数
*/
public class RadixSort {
public static void main(String[] args) {
int[] a = { 0, 9, 5, 6, 12, 31, 1, 23, 15, 100 };
sort(a);
System.out.println(Arrays.toString(a));
// int[] arr = new int[800000];
// for(int i=0; i< arr.length; i++) {
// arr[i] = (int) (Math.random()*800000);
// }
// long start = System.currentTimeMillis();
// sort(arr);
// long end = System.currentTimeMillis();
// System.out.println(end - start);
}
public static void copysort(int[] arr) {
/*
* 需要查找出该数组中位数最多的数
*/
int max = arr[0];
for(int i=0; i<arr.length; i++) {
if(max < arr[i]) {
max = arr[i];
}
}
/*
* 算出该数的位数
*/
int maxLength = (max+"").length();
/*
* 定义十个桶和一个备份数的个数桶
*/
int[][] bucket = new int[10][arr.length];
int[] bucketElementCounts = new int[10];
for(int i=0, n=1; i<maxLength; i++,n *= 10) {
/*
* 先进行装桶
*/
for(int j=0; j<arr.length; j++) {
//获取位数
int digitalElement = arr[j] / n % 10;
//存取到对应的桶中
bucket[digitalElement][bucketElementCounts[digitalElement]] = arr[j];
//同时统计个数
bucketElementCounts[digitalElement]++;
}
/*
* 从头到尾,逐个从桶中取出
*/
int index = 0;
for(int k=0; k<bucketElementCounts.length; k++) {
//如果该桶有个数,就取出
if(bucketElementCounts[k] !=0) {
/*
* 遍历该桶
*/
for(int l=0; l < bucketElementCounts[k]; l++) {
arr[index++] = bucket[k][l];
}
}
//记得清空该标记桶,以便存储的二次的
bucketElementCounts[k]=0;
}
}
}
public static void sort(int arr[]) {
/*
* 先查找出位数最多的数
*/
int num = 99999;
int max = arr[0];
for(int i=0; i<arr.length; i++) {
arr[i] += num;
if(max<arr[i]) {
max = arr[i];
}
}
/*
* 得到位数
*/
int maxLength = (max+"").length();
/*
* 1.定义十个桶
* 2.每个桶的容量为arr.length
* 3.bucketElementCounts为了记录每个桶中的元素个数
*/
int[][] bucket = new int[10][arr.length];
int[] bucketElementCounts = new int[10];
/*
* 开始循环排序
* 1.这是根据位数进行比较的,因此将位数作为循环体
*/
for(int i=0 ,n=1; i<maxLength; i++,n *= 10) {
for(int j=0; j<arr.length; j++) {
//取出元素对应的位数
int digitalElement = arr[j]/n%10;
//根据取出的位数放入对应的桶中
bucket[digitalElement][bucketElementCounts[digitalElement]] = arr[j];
//拷贝
bucketElementCounts[digitalElement]++;
}
/*
* 取出bucket桶中的数据
*/
int index = 0;
for(int k=0; k< bucketElementCounts.length; k++) {
//如果bucketElementCounts桶中有数据,才存储数据到原数组中
if(bucketElementCounts[k]!=0) {
/*
* 从bucket拿取数据
*/
for(int l=0; l<bucketElementCounts[k]; l++) {
arr[index++] = bucket[k][l];
}
}
bucketElementCounts[k] = 0;
}
}
for(int p=0; p<arr.length; p++) {
arr[p] -= num;
}
// System.out.println("排序的结果"+Arrays.toString(arr));
}
}
基数排序
最新推荐文章于 2023-04-13 11:24:26 发布