排序算法-基数排序
基数排序
基数排序(桶排序)介绍:
- 基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或 bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用
- 基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法
- 基数排序(Radix Sort)是桶排序的扩展
- 基数排序是 1887 年赫尔曼·何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。
基数排序基本思想
- 将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
- 这样说明,比较难理解,下面我们看一个图文解释,理解基数排序的步骤
基数排序图文说明
将数组 {53, 3, 542, 748, 14, 214} 使用基数排序, 进行升序排序
基数排序代码实现
要求:将数组 {53, 3, 542, 748, 14, 214} 使用基数排序, 进行升序排序
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 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | package com.xuge.sort; import java.util.Arrays; /** * author: yjx * Date :2022/5/3022:05 **/ public class RadixSort { public static void main(String[] args) { int [] arr = { 53 , 3 , 542 , 748 , 14 , 214 }; redisSort(arr); } public static void redisSort( int [] arr) { //1.得到数组中最大的位数 int max = arr[ 0 ]; for ( int i= 1 ;i<arr.length;i++){ if (max<arr[i]){ max=arr[i]; } } int maxLength = (max + "" ).length(); //2.遍历maxLength轮 for ( int i = 0 ,n= 1 ; i < maxLength; i++,n*= 10 ) { //针对每一个位排序 //1.第一轮排序 针对每个元素各位 //2.二维数组包含10个一维数组,每个一维数组大小定位arr.length; //3.是使用空间换时间的经典算法 int [][] buceket = new int [ 10 ][arr.length]; //为了记录每个桶实际存放的数据个数 //buceketElementCounts[0]记录第0个桶放入数据个数 int [] buceketElementCounts = new int [ 10 ]; for ( int j = 0 ; j < arr.length; j++) { //取出每个元素的个位数 int digitOfElement = arr[j] /n% 10 ; //放入到对应桶中 buceket[digitOfElement][buceketElementCounts[digitOfElement]] = arr[j]; //后移 buceketElementCounts[digitOfElement]++; } //按造这个桶的顺序(一维数组下标,依次取出数据,放入原来数组) int index = 0 ; //遍历每一个桶,依次取数据 for ( int k = 0 ; k < buceketElementCounts.length; k++) { //如果桶中有数据,才放入数据 if (buceketElementCounts[k] != 0 ) { //循环第k个桶,即第k个一维数组 for ( int l = 0 ; l < buceketElementCounts[k]; l++) { //取出元素放入arr[index]中 arr[index++] = buceket[k][l]; } } //第一轮处理后,需要将buceketElementCounts置0 buceketElementCounts[k] = 0 ; } System.out.println( "第" +(i+ 1 )+ "轮排序:" + Arrays.toString(arr)); } /* //1.第一轮排序 针对每个元素各位 //2.二维数组包含10个一维数组,每个一维数组大小定位arr.length; //3.是使用空间换时间的经典算法 int [] [] buceket=new int [10][arr.length]; //为了记录每个桶实际存放的数据个数 //buceketElementCounts[0]记录第0个桶放入数据个数 int []buceketElementCounts=new int [10]; for(int j=0;j<arr.length;j++){ //取出每个元素的个位数 int digitOfElement=arr[j]%10; //放入到对应桶中 buceket[digitOfElement][buceketElementCounts[digitOfElement]]=arr[j]; //后移 buceketElementCounts[digitOfElement]++; } //按造这个桶的顺序(一维数组下标,依次取出数据,放入原来数组) int index=0; //遍历每一个桶,依次取数据 for(int k=0;k<buceketElementCounts.length;k++){ //如果桶中有数据,才放入数据 if(buceketElementCounts[k]!=0){ //循环第k个桶,即第k个一维数组 for(int l=0;l<buceketElementCounts[k];l++){ //取出元素放入arr[index]中 arr[index++]=buceket[k][l]; } } //第一轮处理后,需要将buceketElementCounts置0 buceketElementCounts[k]=0; } System.out.println("第一轮排序:"+ Arrays.toString(arr)); for(int j=0;j<arr.length;j++){ //取出每个元素的十位数 int digitOfElement=arr[j]/10%10; //放入到对应桶中 buceket[digitOfElement][buceketElementCounts[digitOfElement]]=arr[j]; //后移 buceketElementCounts[digitOfElement]++; } //按造这个桶的顺序(一维数组下标,依次取出数据,放入原来数组) index=0; //遍历每一个桶,依次取数据 for(int k=0;k<buceketElementCounts.length;k++){ //如果桶中有数据,才放入数据 if(buceketElementCounts[k]!=0){ //循环第k个桶,即第k个一维数组 for(int l=0;l<buceketElementCounts[k];l++){ //取出元素放入arr[index]中 arr[index++]=buceket[k][l]; } } //第二轮处理后,需要将buceketElementCounts置0 buceketElementCounts[k]=0; } System.out.println("第二轮排序:"+ Arrays.toString(arr)); for(int j=0;j<arr.length;j++){ //取出每个元素的十位数 int digitOfElement=arr[j]/100; //放入到对应桶中 buceket[digitOfElement][buceketElementCounts[digitOfElement]]=arr[j]; //后移 buceketElementCounts[digitOfElement]++; } //按造这个桶的顺序(一维数组下标,依次取出数据,放入原来数组) index=0; //遍历每一个桶,依次取数据 for(int k=0;k<buceketElementCounts.length;k++){ //如果桶中有数据,才放入数据 if(buceketElementCounts[k]!=0){ //循环第k个桶,即第k个一维数组 for(int l=0;l<buceketElementCounts[k];l++){ //取出元素放入arr[index]中 arr[index++]=buceket[k][l]; } } //第二轮处理后,需要将buceketElementCounts置0 buceketElementCounts[k]=0; } System.out.println("第三轮排序:"+ Arrays.toString(arr)); */ } } |
测试速度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public static void main(String[] args) { // int[] arr = {53, 3, 542, 748, 14, 214}; // redisSort(arr); int arr2[] = new int [ 800000 ]; for ( int i = 0 ; i < 800000 ; i++) { arr2[i] = ( int ) (Math.random() * 800000000 ); //生成随机数[0,80000000); } System.out.println( "====输出数组=====" ); Date data = new Date(); SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); String str = sdf.format(data); System.out.println( "排序前的时间是:" + str); //23 redisSort(arr2); Date data2 = new Date(); String str2 = sdf.format(data2); System.out.println( "排序后的时间是" + str2); //25 } |