基数排序详解
思路分析
- 基数排序是典型的以空间换时间的排序算法,但是当对大量数据进行排序时,可能会出现空间不足的情况
- 基数排序实质上是对桶排序的升级,核心思想是对数组中的每个元素从低位到高位开始排序,在较小数据高位补零,使数组中个元素长度相同
- 因此需要大量空间,即创建十个桶用来辅助排序,用二维数组来模拟十个桶,则桶的顺序是实现确定的,将数组中的元素按照某一位的大小依次进行排序,没排序一次,将排好序的结构再存放到原始数组中,然后开始下一轮排序,直到数组元素的最高位也参与过排序
- 注意二维数组在创建后默认所有元素都为0,因此在向二维数组即桶中添加元素中,需要一个索引记录当前桶中的元素个数,方便取出,因此还需要一个一维数组
- 源码及详解如下
源码及详解
/**
* 基数排序,桶排序的升级
*
* @param arr 要排序的数组
*/
public static void radixSort(int[] arr) {
//获取数组中最大元素的位数
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
int maxLength = (max + "").length();
//用二维数组模拟10个桶,即二维数组的每一行代表一个桶
int[][] bucket = new int[10][arr.length];
//定义数组bucketElementCount保存10个桶中实际存储的元素个数
int[] bucketElementCount = new int[10];
//循环处理每一位
for (int k = 0, n = 1; k < maxLength; k++, n *= 10) {
//先将数组中的元素放入桶中
for (int i = 0; i < arr.length; i++) {
int digitOfElement = arr[i] / n % 10;
bucket[digitOfElement][bucketElementCount[digitOfElement]] = arr[i];
bucketElementCount[digitOfElement]++;
}
//按照个位数字大小放置完毕后,将桶中的数字取出来放回到原数组arr
int index = 0;
//遍历存放实际桶中元素个数的一维数组,如果一维数组中索引对应元素=0,说明对应桶中没有元素,不再遍历,
for (int i = 0; i < bucketElementCount.length; i++) {
if (bucketElementCount[i] != 0) {
//否则遍历桶中元素,将其元素重新赋值给原始数组
for (int j = 0; j < bucketElementCount[i]; j++) {
arr[index] = bucket[i][j];
index++;
}
}
//将保存实际桶中元素个数的数字清0
bucketElementCount[i] = 0;
}
}
}