Radix Sort
排序算法——基数排序
基本概念
基数排序(radix sort)
属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用
基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法
- 基数排序(Radix Sort)是桶排序的扩展
基本思想
将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
思路图解
代码
ps:不支持负数
算法代码
基数排序是根据元素的某位数的值进行划分,将对应元素划分到桶里,然后在存入原数组,不断循环以上做法,循环次数是最大元素的位数,当循环完后,顺序也就出来了。从代码上看,也会发现该算法是明显的空间换时间,但明显会感觉到它的循环次数少比较也只在判断时比较,因此达到时间很短。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public static void radixSort(int[] arr) {
int max = Arrays.stream ( arr ).max ( ).getAsInt ( ); int maxLength = ( max + "" ).length ( );
int[][] bucket = new int[ 10 ][ arr.length ]; int[] bucketIndex = 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 ][ bucketIndex[ digitOfElement ] ] = arr[ j ]; bucketIndex[ digitOfElement ]++; }
int index = 0; for ( int x = 0 ; x < bucket.length ; x++ ) {
for ( int y = 0 ; y < bucketIndex[ x ] ; y++ ) { arr[ index ] = bucket[ x ][ y ]; index++; } bucketIndex[ x ] = 0; } System.out.println ( "第" + ( i + 1 ) + "轮结果" + Arrays.toString ( arr ) ); } }
|
性能测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| public class RadixSorting { public static void main ( String[] args ) {
int [] arr = new int[ 80000000 ]; randomArr ( arr ); System.out.println ( "基数排序8000万数据所用时间" ); String date1String = Date ( ); System.out.println ( "排序前时间是:" + date1String ); radixSort ( arr ); String date2String = Date ( ); System.out.println ( "排序后时间是:" + date2String ); }
public static void radixSort(int[] arr) {
int max = Arrays.stream ( arr ).max ( ).getAsInt ( );
int maxLength = ( max + "" ).length ( );
int[][] bucket = new int[ 10 ][ arr.length ]; int[] bucketIndex = 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 ][ bucketIndex[ digitOfElement ] ] = arr[ j ]; bucketIndex[ digitOfElement ]++; }
int index = 0; for ( int x = 0 ; x < bucket.length ; x++ ) {
for ( int y = 0 ; y < bucketIndex[ x ] ; y++ ) { arr[ index ] = bucket[ x ][ y ]; index++; } bucketIndex[ x ] = 0; }
}
}
private static void randomArr ( int[] arr ) { for ( int i = 0 ; i < arr.length ; i++ ) { arr[ i ] = (int) ( Math.random ( ) * 8000000 ); } }
private static String Date ( ) { Date date1 = new Date ( ); SimpleDateFormat simpleFormatter = new SimpleDateFormat ( "HH:mm:ss" ); return simpleFormatter.format ( date1 ); } }
|
结果
PS:上面我们测试8000万个数据来进行测试,就数据产生的空间,我们大致计算一 下,
80000000 X 11 X 4 / 1024 / 1024 / 1024=3.3G
由此可知,虽然它的效率高,但它所产生的内存也十分的巨大。