基数排序法,支持负数排序
1、基本介绍:
1、基数排序法又称为“分配式排序”,他是通过数值的位数的值,将要排序的元素分配到相应的桶中,达到排序的结果,他是桶排序的扩展,是一种效率极高的稳定排序算法。
2、他是一种以空间换时间的经典排序算法,需要大量的电脑内存
3、经过测试,使用基数排序法排序几千万个数据,耗费不到1秒;但是,当排序上亿个数据时,控制台出现内存不足的错误。
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at Sort.ShellSort.ShellSort.RadixSort.Sort.ShellSort.ShellSort.RadixSort.main(Sort.ShellSort.ShellSort.RadixSort.java:12)
2、基本思想:
一个待排序的数组,按个十百千万等位数来划分,这个数组中的最大值是多少位数,就需要排序多少次,从个位数开始。
3、上图:
4、上代码:
package Sort.RadixSort;
/**
* @author 紫风
* @date 2022年03月09日 10:04
*/
public class RadixSort {
public static void main(String[] args) {
// 生成随即数组
int arr[] = new int[10000000];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 1000000000);
}
long l1 = System.currentTimeMillis();
// System.out.println(Arrays.toString(arr));
radixsort(arr);
// System.out.println(Arrays.toString(arr));
long l2 = System.currentTimeMillis();
System.out.println((l2 - l1) / 1000);
}
// 基数排序法
// 当数组大小为一个亿时,出现内存不足的错误
/*
* Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at Sort.ShellSort.ShellSort.RadixSort.Sort.ShellSort.ShellSort.RadixSort.main(Sort.ShellSort.ShellSort.RadixSort.java:12)*/
// 因此,基数排序法是用空间换时间的排序法,需要大量的电脑内存
// 排序一千万个数据,耗费不到一秒
public static void radixsort(int[] arr) {
// 创建二维数组标识桶
int[][] bucket = new int[10][arr.length];
// 记录每个桶存放的数据数量
int count[] = new int[10];
// 将数据放入桶宗
// 三轮整合
// 获取最大的数
// 假设第一个数最大
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
int length = (max + "").length();
for (int l = 0, n = 1; l < length; l++, n *= 10) {
for (int i = 0; i < arr.length; i++) {
// 每个数据取个位
int i1 = arr[i] / n % 10;
bucket[i1][count[i1]] = arr[i];
// count++
count[i1]++;
}
int index = 0;
// 遍历每一个痛取出数据放入原数组
for (int i = 0; i < count.length; i++) {
if (count[i] > 0) {
for (int j = 0; j < count[i]; j++) {
arr[index++] = bucket[i][j];
}
}
// 取完数组后,每个桶的数组数量置零
count[i] = 0;
}
}
/*
// 第一轮
for (int i = 0; i < arr.length; i++) {
// 每个数据取个位
int i1 = arr[i] % 10;
bucket[i1][count[i1]] = arr[i];
// count++
count[i1]++;
}
int index = 0;
// 遍历每一个痛取出数据放入原数组
for (int i = 0; i < count.length; i++) {
if (count[i] > 0) {
for (int j = 0; j < count[i]; j++) {
arr[index++] = bucket[i][j];
}
}
// 取完数组后,每个桶的数组数量置零
count[i] = 0;
}
// 第二轮
for (int i = 0; i < arr.length; i++) {
// 每个数据取十位数值
int i1 = arr[i] / 10 % 10;
bucket[i1][count[i1]] = arr[i];
// count++
count[i1]++;
}
// arr数组索引置零
index = 0;
// 遍历每一个痛取出数据放入原数组
for (int i = 0; i < count.length; i++) {
if (count[i] > 0) {
for (int j = 0; j < count[i]; j++) {
arr[index++] = bucket[i][j];
}
}
count[i] =0;
}
// 第三轮
for (int i = 0; i < arr.length; i++) {
// 每个数据取十位数值
int i1 = arr[i] / 100 % 10;
bucket[i1][count[i1]] = arr[i];
// count++
count[i1]++;
}
// arr数组索引置零
index = 0;
// 遍历每一个痛取出数据放入原数组
for (int i = 0; i < count.length; i++) {
if (count[i] > 0) {
for (int j = 0; j < count[i]; j++) {
arr[index++] = bucket[i][j];
}
}
count[i] =0;
}*/
}
}