一、基数排序描述

  基数排序(radix sort)属于"分配式排序"(distribution sort),又称"桶子法"(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些"桶"中,藉以达到排序的作用,基数排序法是属于稳定性的排序。基数排序有二种实现方式:最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。最低位优先(Least Significant Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。

二、基本思路

  基数排序采用最低优先的方式,将所有待排序数列元素统一为同样的数位长度,数列元素数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

三、实现步骤

  1. 找到数列元素的个位数,然后以个位数为桶的索引,将数列元素存放在桶中。
  2. 遍历桶,将桶的数据元素取出依次存放在原数组中。
  3. 找到数列元素的高位数,重复1,2操作,直到找操作完最高位数,这时数列就有序了。

四、案例分析

以数组{6,5,7,3,1,12,33,53,25,89,108,149,44,87,36}为例:

第一轮按个位数排序如下图:每一列为一个桶

0 1 2 3 4 5 6 7 8 9
  1 12 3 44 5 6 7 108 89
      33   25 36 87   149
      53            

按各位排序结果为:{1, 12, 3, 33, 53, 44, 5, 25, 6, 36, 7, 87, 108, 89, 149}

第二轮按十位数排序如下图:每一列为一个桶

0 1 2 3 4 5 6 7 8 9
 1 12 25 33 44 53     89  
 3     36 149     87    
5                  
6                  
7                  
108                  

按十位排序结果为:{1, 3, 5, 6, 7, 108, 12, 25, 33, 36, 44, 149, 53, 87, 89}

第三轮按百位数排序如下图:每一列为一个桶

0 1 2 3 4 5 6 7 8 9
1 108                
3 149                
5                  
6                  
7                  
12                  
25                  
33                  
36                  
44                  
53                  
87                  
89                  

按百位位排序结果为:{1, 3, 5, 6, 7, 12, 25, 33, 36, 44, 53, 87, 89, 108, 149},百位排序完成这个排序操作已经完成了。

五、代码实现

public class JavaSort {
public static void main(String[] args) {
int a [] =new int []{6,5,7,3,1,12,33,53,25,89,108,149,44,87,36};
System.out.println("排序前的数组:"+Arrays.toString(a));
bucketSort(a);
System.out.println("排序后的数组:"+Arrays.toString(a));
} /**
* 该排序一共需要排序最大元素位数次排序,假如数组元素的最大值为345,那么需要排序三轮,第一轮按照个位数进行排序
* 第二轮按照十位位数进行排序,第三轮按照百位数进行排序。
* @param ary 未排序数据
*/
private static void bucketSort(int[] ary) { int aryLen=ary.length;
int len=aryLen;
if(aryLen<=10) {
len=10;
}
int bucket [][] =new int [10][len];//用于存放每次排序存放的结果。
int bucketCap []=new int[len];//每个桶子存放的数据量。bucketCap[i]表示i个桶有多少个数据量,所以len必须大于等于10
int loop=1;//排序的轮数,第一次按个位数上的数字排序,第二次按照十位数上的数字排序
int maxLoop=getMaxLoop(ary);//排序需要的最大轮数,即是数组元素中最大元素是几位数。
int k=0;//每轮排序好的数据存放的索引位置
while(loop<=maxLoop) {
for (int i = 0; i < aryLen; i++) {//将数组元素存放在相应的桶里面
int position=(int) (ary[i]/(Math.pow(10, loop-1))%10);//取出要排的数据,第一轮取出个位数,第二轮取出十位数...,,也是数组元素存放在哪个桶子中,桶子的索引值。
bucket[position][bucketCap[position]]=ary[i];
bucketCap[position]++;
} for (int i = 0; i < 10; i++) {//遍历所有的桶子,取出桶子的值,存放在原数组完成一轮排序
if(bucketCap[i]>0) {
for (int j = 0; j < bucketCap[i]; j++) {
ary[k]=bucket[i][j];
k++;
}
bucketCap[i]=0;//将桶子清空
}
}
System.out.println("第"+loop+"轮排序结果为"+Arrays.toString(ary));
loop++;//轮数加+
k=0;
} } /**
* 获取数组元素最大值的位数。
* @param ary
* @return 最大数的位数
*/ private static int getMaxLoop(int[] ary) {
int max=ary[0];
for (int i = 1; i < ary.length; i++) {
if(max<ary[i]) {
max=ary[i];
}
}
int temp=max;
int n=1;
while((temp=temp/10)>0) {
n=n+1;
} return n;
} }

六、运行结果已经效率分析

效率分析:

时间复杂度为:O(n),空间复杂度为:O(10*n)

java方式实现基数排序的更多相关文章

  1. EBS中使用JAVA方式发送HTML格式邮件

    转自huan.gu专栏:http://blog.csdn.net/gh320/article/details/17174769 EBS中使用JAVA方式发送HTML格式邮件 一.开发工具:JDevel ...

  2. 配置RedisTemplate、JedisPoolConfig、JedisConnectionFactory+自定义序列化 (xml+java方式)+使用

    java方式配置RedisTemplate //spring注入ben //@Bean(name = "redisTemplate") public RedisTemplate i ...

  3. spring配置redis(xml+java方式)(最底层)

    条件:引用好架包 <dependency> <groupId>org.springframework.data</groupId> <artifactId&g ...

  4. Java方式配置Spring MVC

    概述 使用Java方式配置Spring MVC,以及回顾一下Spring MVC的各种用法. Spring MVC简述 关于Spring MVC的介绍网上有很多,这里就不再赘述了,只是要说一下,Spr ...

  5. SpringBoot-配置Java方式

    SpringBoot中使用Java方式配置步骤如下: 在类上加入@Configuration注解,代表作为配置类 在该类方法上加入@Bean注解,代表将方法返回的Bean加入Spring容器 在该类中 ...

  6. 算法-java代码实现基数排序

    基数排序 第11节 基数排序练习题 对于一个int数组,请编写一个基数排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组.保证元素均小于等于2000. 测试样例: [1 ...

  7. 使用Java方式连接HDFS

    IDEA中新建Maven工程,添加POM依赖, 在IDE的提示中, 点击 Import Changes 等待自动下载完成相关的依赖包. <?xml version="1.0" ...

  8. 跨域问题Java方式解决及Nginx方式解决【亲测可行】

    这两天和前端同事调试微信公众号项目,就遇到了跨域问题:网上相关博客也挺多的,但有很多细节没有点到,在此呢我也再次记录一下解决方式: (算是踩坑日记吧~ ~ ~)   !问题发现: 页面加载不出来,控制 ...

  9. Java方式bean的注入以及自动配置

    Java配置 Java配置的本质上,就是使用一个Java类去代替xml配置,这种配置方式在目前最主流的Spring Boot中得到了广泛的使用.1.引入相关Spring相关依赖 2.创建Java配置类 ...

随机推荐

  1. Unix的I/O模型

    对于一次I/O操作(以read为例),数据首先被拷贝到内核的某个缓冲区,然后再从内核缓冲区拷贝到应用进程缓冲区. 因此,一次I/O操作通常包含两个阶段: (1) 等待数据准备好 (2) 从内核向进程复 ...

  2. Eating Everything Efficiently(反向dp)

    传送门 取最大值即可.用拓扑,dfs都可以实现 #include <bits/stdc++.h> using namespace std; const int maxn=500009; i ...

  3. E. Marbles 状压dp

    E. Marbles 这个是一个状压dp 题目大意是:给你一个数组,数组的数在1到20之间,有一个操作就是交换相邻的两个数,问 让所有相同的数相邻的最小操作次数 dp[s] 表示s状态下的操作次数,w ...

  4. Tunnel Warfare 线段树 区间合并|最大最小值

    B - Tunnel WarfareHDU - 1540 这个有两种方法,一个是区间和并,这个我个人感觉异常恶心 第二种方法就是找最大最小值 kuangbin——线段树专题 H - Tunnel Wa ...

  5. Java 函数式接口

    目录 Java 函数式接口 1. 函数式接口 1.1 概念 1.2 格式 1.3 函数式接口的使用 2. 函数式编程 2.1 Lambda的延迟执行 性能浪费的日志案例 使用Lambda表达式的优化 ...

  6. python gdal 读取栅格数据

    1.gdal包简介 gdal是空间数据处理的开源包,其支持超过100种栅格数据类型,涵盖所有主流GIS与RS数据格式,包括Arc/Info ASCII Grid(asc),GeoTiff (tiff) ...

  7. 【Spark】快来学习RDD的创建以及操作方式吧!

    目录 RDD的创建 三种方式 从一个集合中创建 从文件中创建 从其他的RDD转化而来 RDD编程常用API 算子分类 Transformation 概述 帮助文档 常用Transformation表 ...

  8. 【Hadoop离线基础总结】网站流量日志数据分析系统

    目录 点击流数据模型 概述 点击流模型 网站流量分析 网站流量模型分析 网站流量来源 网站流量多维度细分 网站内容及导航分析 网站转化及漏斗分析 流量常见分析角度和指标分类 指标概述 指标分类 分析角 ...

  9. 关于form表单的reset

    今天写代码想重置一个表单,一出手就是$("#formid").reset().结果表单纹丝不动数据都还在一点效果都没有. 后来找时间百度了下jquery的api,确实没有reset ...

  10. 记录下做攻防世界的misc题

    0x00 记录一下,代表自己做过 0x01 flag_universe 看简介是来自2018年的百越杯. 将文件下载下来后,就一个flag_universe.pcapng文件,wireshark打开. ...