基本介绍
先分配后收集。从个位数开始将数据分配到对应数字桶中,然后再收集回原数组,依次处理到高位数为止。
——爱因斯坦
核心思想
- 基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用;
- 基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法;
- 基数排序(Radix Sort)是桶排序的扩展;
- 基数排序是1887年赫尔曼·何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。
实例讲解
主要思路
将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
图示演示
代码实现
Talk is cheap, show me the code.
import java.io.*;
import java.util.*;
//Author:Peiliang Gong
//DataStructure:[Josephu implemented by CircleSingleLinkedList]
class Sort
{
//main function
public static void main (String[] args) throws java.lang.Exception
{
int[] arr = {3,1,56,0,0,7,2,4};
radixSort(arr);
System.out.println("排序后的结果为:"+Arrays.toString(arr));
}
private static void radixSort(int[] arr){
//首先找到数组中的最大数,为了确定一共有多少位数
int max = arr[0];
for(int i = 1; i < arr.length; i++){
if(max < arr[i]){
max = arr[i];
}
}
int maxLen = (max+"").length();
//定义两个数组,其中一个二维数组用来存放每个数字对应的数,一维数组用来统计每个数字桶内的数字个数
int buket[][] = new int[10][arr.length];
int buketCount[] = new int[10];
//外层循环遍历最大数字位数
for(int i = 0, n = 1; i < maxLen; i++, n*=10){
//内层循环遍历数组中的所有数据,然后取出对应的位数将其放入到对应的数字桶内[分配步骤]
for(int j = 0; j < arr.length; j++){
//each digit
int digit = arr[j] / n % 10;
buket[digit][buketCount[digit]] = arr[j];
buketCount[digit]++;
}
//将桶内所有的数字按照0-9的顺序依次取出放回原始的数组中[收集步骤]
int index = 0;
for(int k = 0; k < buketCount.length; k++){
if(buketCount[k] != 0){
for(int b = 0; b < buketCount[k]; b++){
arr[index++] = buket[k][b];
}
}
//注意每次收集之后要将统计每个桶内数据个数的数组值置为0,以便下一轮可以继续统计个数
buketCount[k] = 0;
}
}
}
}