Java编程:排序算法——基数排序
基数排序(桶排序)介绍:
- 基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用
- 基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法
- 基数排序(Radix Sort)是桶排序的扩展
- 基数排序是1887年赫尔曼·何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。
基数排序基本思想
- 将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
- 这样说明,比较难理解,下面我们看一个图文解释,理解基数排序的步骤
基数排序图文说明
将数组 {53, 3, 542, 748, 14, 214} 使用基数排序, 进行升序排序。
基数排序代码实现
- 要求:将数组 {53, 3, 542, 748, 14, 214 } 使用基数排序, 进行升序排序
- 思路分析:前面的图文已经讲明确
代码
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));}
}
基数排序的说明
- 基数排序是对传统桶排序的扩展,速度很快.
- 基数排序是经典的空间换时间的方式,占用内存很大, 当对海量数据排序时,容易造成 OutOfMemoryError 。
- 基数排序时稳定的。[注:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的]
- 有负数的数组,我们不用基数排序来进行排序, 如果要支持负数,参考: https://code.i-harness.com/zh-CN/q/e98fa9
Java编程:排序算法——基数排序相关推荐
- 在线编程——排序算法总结
在线编程--排序算法总结 找实习,阿里一面遇到手写快排,写出来感觉没错(VS2013能通过),但在阿里的测试平台上运行未通过.细思极恐,赶紧总结一波.有幸看到SteveWang的两篇博客:排序算法总结 ...
- Java经典排序算法
提示:本文仅供自己学习 Java经典排序算法 一.排序算法概念及分类 1.排序概念 2.排序分类 二.十大排序算法 1.冒泡排序(BubbleSort) 2.选择排序(Selection sort) ...
- Java常见排序算法
Java常见排序算法 转载于:https://www.cnblogs.com/hfultrastrong/p/7829889.html
- Java常见排序算法之插入排序
一.概述 本节由小千给大家分享Java常见排序算法之插入排序,之前我们说过排序是算法中的一部分.所以我们学习排序也是算法的入门,为了能让大家感受到排序是算法的一部分,我举个例子证明一下:比如麻将游戏, ...
- java treemap 排序原理,Java TreeMap排序算法实例
本文实例讲述了Java TreeMap排序算法.分享给大家供大家参考,具体如下: TreeMap 和 HashMap 用法大致相同,但实际需求中,我们需要把一些数据进行排序: 以前在项目中,从数据库查 ...
- Java经典排序算法:选择排序,动图演示排序过程
Java经典排序算法:选择排序,动图演示排序过程 示意动图: public class Main {public static void main(String[] args) {new Main() ...
- Java常用排序算法/程序员必须掌握的8大排序算法
本文由网络资料整理而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配排序(基数 ...
- ef 排序string转int_Java排序算法——基数排序(Radix Sort)
基数排序 基数排序是非比较的排序算法,对每一位进行排序,从最低位开始排序,复杂度为O(kn),为数组长度,k为数组中的数的最大的位数: 基数排序是按照低位先排序,然后收集:再按照高位排序,然后再收集: ...
- Java常见排序算法之直接选择排序
在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...
- Java常见排序算法之堆排序
在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...
最新文章
- 软定时器的原理与创建
- python 山脉数组的峰顶索引
- DCMTK:将XML文档的内容转换为DICOM结构的报告文件
- 滴滴李先刚:语音识别在复杂场景的性能将显著提升
- uWSGI 和 nginx 的区别?
- 一文看懂数据预处理最重要的3种思想和方法
- 各种电子元器件介绍与电路基础作用
- html网页设计作业代码web网页设计实例作业 ——放飞梦想文化主题(3页)
- 手机变速齿轮_变速齿轮手机版下载|变速齿轮游戏加速器官方最新版v1.2下载 _当游网...
- 怎样在vue中使用jquery
- Suspending Methods【暂停方法队列说明】
- nn.Sigmoid torch
- 金融市场一周简报(2017-08-18)
- yii 高级版后台清理前台的缓存
- 「Cold Chain 2015国际冷链物流展」
- AirDisk存宝 【S3\S6简易使用说明】
- Linux JKD1.8 安装及配置
- git 提交修改备注
- CAD2020安装完毕,打开提示“许可管理器不起作用或未正确安装” 解决思路
- matlab三维集装3D container箱装箱优化【matlab优化算法七】
热门文章
- 120. strtotime()
- 41. Element getElementsByTagName() 方法
- 10. 获取Magento域名及图片,JS路径方法
- Spring事务管理—aop pointcut expression解析
- 【SQL】Mysql常用sql语句记录
- MySQL · 引擎特性 · 基于InnoDB的物理复制实现(转载)
- SPFA - Luogu 3385 【模板】负环
- complexType
- Pop3_解决PKIX:unable to find valid certification path to requested target 的问题
- 关于web开发的一点理解