基数排序
经过尚硅谷韩顺平老师的视频讲解 总结下来的笔记
基数排序
基数排序(桶排序)介绍:
1)基数排序(radixsopt)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用
2)基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法
3)基数排序(Radix Sort)是桶排序的扩展
4)基数排序是1887年赫尔曼·何乐礼发明的。它是这样实现的:将整数按位数切
割成不同的数字,然后按每个位数分别比较。
基数排序基本思想
1)将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
拆开分析
@Test
public void name() {
int[] arr = {53, 3, 542, 748, 14, 214};
//定义一个二维数组 表示10个桶 每个桶就是一个一维数组
//1。二维数组包含10个一维数组
//2。为了防止在放入数的时候,数据溢出
//空间换时间
int[][] bucket = new int[10][arr.length];
//为了记录每个桶中,实际存放了多少个数据,我们定义一个一维数组来记录各个桶的每次放入的数据个数
int[] bucketElementCounts = new int[10];
/**
* 第一轮(对每个元素的个位进行排序)
*/
for (int j = 0; j < arr.length; j++) {
//取出每个元素的个位
int digitOfElement = arr[j] % 10;
//放到对应的桶
bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
bucketElementCounts[digitOfElement]++;
}
//按照桶的顺序 (一维数组的下标依次取出数据,放入原来的数组)
int index = 0;
//遍历每一桶,并将桶中的数据放入到原数组
for (int k = 0; k < bucket.length; k++) {
//如果桶中有数据 放入到原数组
if (bucketElementCounts[k] != 0) {
//循环第k个桶(一维数组)
for (int l = 0; l < bucketElementCounts[k]; l++) {
//取出元素放入arr
arr[index] = bucket[k][l];
index++;
}
}
//bucketElementCounts[k] 置零!!!!
bucketElementCounts[k] = 0;
}
System.out.println("第一轮:(个位排序处理)" + Arrays.toString(arr));
//============================================================================
/**
* 第二轮(对每个元素的十位进行排序)
*/
for (int j = 0; j < arr.length; j++) {
//取出每个元素的个位
int digitOfElement = arr[j] / 10 % 10;
//放到对应的桶
bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
bucketElementCounts[digitOfElement]++;
}
//按照桶的顺序 (一维数组的下标依次取出数据,放入原来的数组)
index = 0;
//遍历每一桶,并将桶中的数据放入到原数组
for (int k = 0; k < bucket.length; k++) {
//如果桶中有数据 放入到原数组
if (bucketElementCounts[k] != 0) {
//循环第k个桶(一维数组)
for (int l = 0; l < bucketElementCounts[k]; l++) {
//取出元素放入arr
arr[index] = bucket[k][l];
index++;
}
}
//bucketElementCounts[k] 置零!!!!
bucketElementCounts[k] = 0;
}
System.out.println("第二轮:(十位排序处理)" + Arrays.toString(arr));
//================================================================
/**
* 第三轮(对每个元素的百位进行排序)
*/
for (int j = 0; j < arr.length; j++) {
//取出每个元素的个位
int digitOfElement = arr[j] / 100 % 10;
//放到对应的桶
bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
bucketElementCounts[digitOfElement]++;
}
//按照桶的顺序 (一维数组的下标依次取出数据,放入原来的数组)
index = 0;
//遍历每一桶,并将桶中的数据放入到原数组
for (int k = 0; k < bucket.length; k++) {
//如果桶中有数据 放入到原数组
if (bucketElementCounts[k] != 0) {
//循环第k个桶(一维数组)
for (int l = 0; l < bucketElementCounts[k]; l++) {
//取出元素放入arr
arr[index] = bucket[k][l];
index++;
}
}
//bucketElementCounts[k] 置零!!!!
bucketElementCounts[k] = 0;
}
System.out.println("第三轮:(百位排序处理)" + Arrays.toString(arr));
}
整体代码
public static void radixSort(int[] arr) {
//1。得到数组中最大的数的位数
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
//得到最大数是几位
int maxLength = (max + "").length();
//定义一个二维数组 表示10个桶 每个桶就是一个一维数组
//1。二维数组包含10个一维数组
//2。为了防止在放入数的时候,数据溢出
//空间换时间
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 digitOfElement = (arr[j] / n % 10);
//放到对应的桶
bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
bucketElementCounts[digitOfElement]++;
}
//按照桶的顺序 (一维数组的下标依次取出数据,放入原来的数组)
int index = 0;
//遍历每一桶,并将桶中的数据放入到原数组
for (int k = 0; k < bucket.length; k++) {
//如果桶中有数据 放入到原数组
if (bucketElementCounts[k] != 0) {
//循环第k个桶(一维数组)
for (int l = 0; l < bucketElementCounts[k]; l++) {
//取出元素放入arr
arr[index] = bucket[k][l];
index++;
}
}
//bucketElementCounts[k] 置零!!!!
bucketElementCounts[k] = 0;
}
System.out.println("第" + (i + 1) + "轮:" + Arrays.toString(arr));
}
}