基数排序(桶排序)介绍:

  1. 基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用
  2. 基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法
  3. 基数排序(Radix Sort)是桶排序的扩展
  4. 基数排序是1887年赫尔曼·何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。

基数排序基本思想

  1. 将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
  2. 这样说明,比较难理解,下面我们看一个图文解释,理解基数排序的步骤

基数排序图文说明

将数组 {53, 3, 542, 748, 14, 214} 使用基数排序, 进行升序排序。

基数排序代码实现

  1. 要求:将数组 {53, 3, 542, 748, 14, 214 } 使用基数排序, 进行升序排序
  2. 思路分析:前面的图文已经讲明确

代码

package sort;import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;public class RadixSort {public static void main(String[] args) {//        int[] arr = {53, 3, 542, 748, 14, 214};
//        radixSort(arr);
//        System.out.println(Arrays.toString(arr));int[] arr = new int[80000];for (int i = 0; i < 80000; i++) {arr[i] = (int) (Math.random() * 80000);// 生成一个0-80000的数据}Date date1 = new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String date1Str = simpleDateFormat.format(date1);System.out.println("排序前的时间为:" + date1Str);radixSort(arr);Date date2 = new Date();String date2Str = simpleDateFormat.format(date2);System.out.println("排序后的时间为:" + date2Str);}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];}}// 2.需要得到数组中最大的数的位数int maxLength = (max + "").length();// 前面代码仍然不动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];}int index = 0;for (int k = 0; k < bucketElementCounts.length; k++) {if (bucketElementCounts[k] != 0) {for (int l = 0; l < bucketElementCounts[k]; l++) {arr[index++] = bucket[k][l];}bucketElementCounts[k] = 0;}}}}// 基数排序public static void radixSort1(int[] arr) {// 定义一个二维数组,表示十个桶,每个桶就是一个一维数组// 说明// 1. 二维数组包含10个一维数组// 2. 为了防止在放入数字的时候,产生数据溢出错误,则每个一维数组(桶)的大小为arr.length// 3. 很明显,基数排序是使用空间换时间的经典算法int[][] bucket = new int[10][arr.length];// 为了记录每个桶中实际存放了多少个数据,我们定义一个一维数组,记录各个桶的每次放入的数据个数// 可以这么理解// bucketElementCounts[0] 记录的就是bucket[0]桶的放入数据的个数int[] bucketElementCounts = new int[10];// 第一轮排序(针对每个元素的个位进行排序处理)for (int i = 0; i < arr.length; i++) {// 取出每个元素的个数int digitOfElement = arr[i] / 1 % 10;// 放入到对应桶中,并将记录桶中个数的数组进行++操作bucket[digitOfElement][bucketElementCounts[digitOfElement]++] = arr[i];}// 按照这个桶的顺组(一维数组的下标依次取出数据,放入原来数组)int index = 0;// 1. 遍历每一个桶。并将桶中的数据,放入到原数组for (int i = 0; i < bucketElementCounts.length; i++) {// 如果桶中有数据,我们才放入到原数组if (bucketElementCounts[i] != 0) {// 循环该桶即第k个桶(即第k个一维数组),放入原数组for (int j = 0; j < bucketElementCounts[i]; j++) {// 去除元素,放入到arrarr[index++] = bucket[i][j];}bucketElementCounts[i] = 0;}}System.out.println("第一轮对个位的排序处理arr=" + Arrays.toString(arr));// 第二轮排序(针对每个元素的十位进行排序处理)for (int i = 0; i < arr.length; i++) {// 取出每个元素的个数int digitOfElement = arr[i] / 10 % 10;// 放入到对应桶中,并将记录桶中个数的数组进行++操作bucket[digitOfElement][bucketElementCounts[digitOfElement]++] = arr[i];}// 按照这个桶的顺组(一维数组的下标依次取出数据,放入原来数组)index = 0;// 1. 遍历每一个桶。并将桶中的数据,放入到原数组for (int i = 0; i < bucketElementCounts.length; i++) {// 如果桶中有数据,我们才放入到原数组if (bucketElementCounts[i] != 0) {// 循环该桶即第k个桶(即第k个一维数组),放入原数组for (int j = 0; j < bucketElementCounts[i]; j++) {// 去除元素,放入到arrarr[index++] = bucket[i][j];}// 第一轮处理后,需要将每个bucketElementCounts[k] 置0bucketElementCounts[i] = 0;}}System.out.println("第二轮对个位的排序处理arr=" + Arrays.toString(arr));// 第三轮排序(针对每个元素的百位进行排序处理)for (int i = 0; i < arr.length; i++) {// 取出每个元素的个数int digitOfElement = arr[i] / 100 % 10;// 放入到对应桶中,并将记录桶中个数的数组进行++操作bucket[digitOfElement][bucketElementCounts[digitOfElement]++] = arr[i];}// 按照这个桶的顺组(一维数组的下标依次取出数据,放入原来数组)index = 0;// 1. 遍历每一个桶。并将桶中的数据,放入到原数组for (int i = 0; i < bucketElementCounts.length; i++) {// 如果桶中有数据,我们才放入到原数组if (bucketElementCounts[i] != 0) {// 循环该桶即第k个桶(即第k个一维数组),放入原数组for (int j = 0; j < bucketElementCounts[i]; j++) {// 去除元素,放入到arrarr[index++] = bucket[i][j];}// 第一轮处理后,需要将每个bucketElementCounts[k] 置0bucketElementCounts[i] = 0;}}System.out.println("第三轮对个位的排序处理arr=" + Arrays.toString(arr));}
}

基数排序的说明

  1. 基数排序是对传统桶排序的扩展,速度很快.
  2. 基数排序是经典的空间换时间的方式,占用内存很大, 当对海量数据排序时,容易造成 OutOfMemoryError 。
  3. 基数排序时稳定的。[注:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的]
  4. 有负数的数组,我们不用基数排序来进行排序, 如果要支持负数,参考: https://code.i-harness.com/zh-CN/q/e98fa9

Java编程:排序算法——基数排序相关推荐

  1. 在线编程——排序算法总结

    在线编程--排序算法总结 找实习,阿里一面遇到手写快排,写出来感觉没错(VS2013能通过),但在阿里的测试平台上运行未通过.细思极恐,赶紧总结一波.有幸看到SteveWang的两篇博客:排序算法总结 ...

  2. Java经典排序算法

    提示:本文仅供自己学习 Java经典排序算法 一.排序算法概念及分类 1.排序概念 2.排序分类 二.十大排序算法 1.冒泡排序(BubbleSort) 2.选择排序(Selection sort) ...

  3. Java常见排序算法

    Java常见排序算法 转载于:https://www.cnblogs.com/hfultrastrong/p/7829889.html

  4. Java常见排序算法之插入排序

    一.概述 本节由小千给大家分享Java常见排序算法之插入排序,之前我们说过排序是算法中的一部分.所以我们学习排序也是算法的入门,为了能让大家感受到排序是算法的一部分,我举个例子证明一下:比如麻将游戏, ...

  5. java treemap 排序原理,Java TreeMap排序算法实例

    本文实例讲述了Java TreeMap排序算法.分享给大家供大家参考,具体如下: TreeMap 和 HashMap 用法大致相同,但实际需求中,我们需要把一些数据进行排序: 以前在项目中,从数据库查 ...

  6. Java经典排序算法:选择排序,动图演示排序过程

    Java经典排序算法:选择排序,动图演示排序过程 示意动图: public class Main {public static void main(String[] args) {new Main() ...

  7. Java常用排序算法/程序员必须掌握的8大排序算法

    本文由网络资料整理而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配排序(基数 ...

  8. ef 排序string转int_Java排序算法——基数排序(Radix Sort)

    基数排序 基数排序是非比较的排序算法,对每一位进行排序,从最低位开始排序,复杂度为O(kn),为数组长度,k为数组中的数的最大的位数: 基数排序是按照低位先排序,然后收集:再按照高位排序,然后再收集: ...

  9. Java常见排序算法之直接选择排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  10. Java常见排序算法之堆排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

最新文章

  1. 软定时器的原理与创建
  2. python 山脉数组的峰顶索引
  3. DCMTK:将XML文档的内容转换为DICOM结构的报告文件
  4. 滴滴李先刚:语音识别在复杂场景的性能将显著提升
  5. uWSGI 和 nginx 的区别?
  6. 一文看懂数据预处理最重要的3种思想和方法
  7. 各种电子元器件介绍与电路基础作用
  8. html网页设计作业代码web网页设计实例作业 ——放飞梦想文化主题(3页)
  9. 手机变速齿轮_变速齿轮手机版下载|变速齿轮游戏加速器官方最新版v1.2下载 _当游网...
  10. 怎样在vue中使用jquery
  11. Suspending Methods【暂停方法队列说明】
  12. nn.Sigmoid torch
  13. 金融市场一周简报(2017-08-18)
  14. yii 高级版后台清理前台的缓存
  15. 「Cold Chain 2015国际冷链物流展」
  16. AirDisk存宝 【S3\S6简易使用说明】
  17. Linux JKD1.8 安装及配置
  18. git 提交修改备注
  19. CAD2020安装完毕,打开提示“许可管理器不起作用或未正确安装” 解决思路
  20. matlab三维集装3D container箱装箱优化【matlab优化算法七】

热门文章

  1. 120. strtotime()
  2. 41. Element getElementsByTagName() 方法
  3. 10. 获取Magento域名及图片,JS路径方法
  4. Spring事务管理—aop pointcut expression解析
  5. 【SQL】Mysql常用sql语句记录
  6. MySQL · 引擎特性 · 基于InnoDB的物理复制实现(转载)
  7. SPFA - Luogu 3385 【模板】负环
  8. complexType
  9. Pop3_解决PKIX:unable to find valid certification path to requested target 的问题
  10. 关于web开发的一点理解