算法九之基数排序

一、基数排序

(1)基数排序的简介

  基数排序不同于其他的排序算法,它不是基于比较的算法。基数排序是一种借助多关键字排序的思想对单逻辑关键字进行排序的方法。它是一种稳定的排序算法。 

  通常用于对数的排序选择的是最低位优先法,即先对最次位关键字进行排序,再对高一位的关键字进行排序,以此类推。

(2)基数排序的思想

  多关键字排序中有两种方法:最高位优先法(MSD)和最低位优先法(LSD)。

元数据为k1k2k3..kn

A、最高位优先(Most Significant Digit first)法:
先按k1排序分组,同一k1组中记录关键码k1相等,对各k1组按k2关键字排序分成k2子组;同一k2子组中记录关键码k2相等,再对各k2子组按k3排序分成k3子组,重复这样步骤直至子组按kn排序分成kn子组。再将各组连接起来,便得到一个有序序列。
B、最低位优先(Least Significant Digit first)法:
先从kn开始排序,再对kn-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。

 

二、最高位优先(Most Significant Digit first)法

    public static void radixSort(int[] data) {//位数if(data.length<2)return;int place = getPlace(data);//位数大于0if (place > 0) {sortUnit(data, 0, data.length, 1, place);}}/*** MSD算法* @param data* @param s  起始位置* @param e  截止位置,是最后一个数据的索引+1* @param curPlace  当前所在数据位置,从左边开始,起始值为1* @param totalPlace 最大数据的位数*/private static void sortUnit(int[] data, int s, int e, int curPlace, int totalPlace) {//十个桶int[] counts = new int[10];int p;//计算各个桶的数据个数for (int i = s; i < e; i++) {p = getDigit(data[i], curPlace,totalPlace);//获取数据当前位的值counts[p]++;}//计算各个桶的数据右边索引界限for (int i = 1; i < counts.length; i++) {counts[i] = counts[i] + counts[i - 1];}//创建数组,将所有桶都存放在这个数组里面int[] bucket = new int[e - s];int dat;//从右往左扫描,保证了算法的稳定性for (int i = e-1; i >=s; i--) {dat = data[i];p = getDigit(dat, curPlace,totalPlace); //获取数据当前位的值counts[p]--; //找到属于桶的最后一个位置bucket[counts[p]] = dat;}//将数据回填回dataSystem.arraycopy(bucket, 0, data, s, bucket.length);int start;int end;//根据Ki分组的每个桶都去创建根据Ki+1分组的子桶for (int i = 0; i < counts.length; i++) {start = s + counts[i];//左边界//右边界if (i + 1 < counts.length) {end = s + counts[i + 1];} else {end = e;}//桶里数据大于2,基数位置未到Kn,继续分子桶if (end - start > 1 && curPlace < totalPlace) {sortUnit(data, start, end, curPlace + 1, totalPlace);}}}

 

其他方法调用

    /*** 获取第curPlace位的数值* @param d* @param curPlace* @return */private static int getDigit(int d, int curPlace,int totalPlace) {d=d/((int) Math.pow(10, totalPlace-curPlace));return d % 10;}/*** 获取元数据的位数** @param data* @return*/private static int getPlace(int[] data) {//null值或者长度为0if (data == null || data.length < 1) {return 0;}if(data.length==1){return String.format("%d", data[0]).length();}int[] mx = getMaxAndMin(data);//最大值的绝对值int max = Math.abs(mx[0]);//最小值的绝对值int min = Math.abs(mx[1]);//最大值的绝对值的十进制位数max = String.format("%d", max).length();//最小值的绝对值的十进制位数min = String.format("%d", min).length();return Math.max(max, min);//最大位数
    }/*** 获取最大和最小值* @param data* @return */public static int[] getMaxAndMin(int[] data) {int[] mx = {Integer.MIN_VALUE, Integer.MAX_VALUE};for (int d : data) {if (mx[0] < d) {mx[0] = d;} else if (mx[1] > d) {mx[1] = d;}         }return mx;}
View Code

 

三、最低位优先(Least Significant Digit first)法

    public static void radixSort(int[] data) {//位数if (data.length < 2) {return;}int place = getPlace(data);//位数大于0for (int i = 0; i < place; i++) {sortUnit(data, i);}}/*** LSD算法** @param data* @param curPlace 当前所在数据位置,从右边开始,起始值为0*/private static void sortUnit(int[] data, int curPlace) {//十个桶int[] counts = new int[10];int p;//计算各个桶的数据个数for (int i = 0; i < data.length; i++) {p = getDigit(data[i], curPlace);//获取数据当前位的值counts[p]++;}//计算各个桶的数据右边索引界限for (int i = 1; i < counts.length; i++) {counts[i] = counts[i] + counts[i - 1];}//创建数组,将所有桶都存放在这个数组里面int[] bucket = new int[data.length];int dat;//从右往左扫描,保证了算法的稳定性for (int i = data.length - 1; i >= 0; i--) {dat = data[i];p = getDigit(dat, curPlace); //获取数据当前位的值counts[p]--; //找到属于桶的最后一个位置bucket[counts[p]] = dat;}//将数据回填回dataSystem.arraycopy(bucket, 0, data, 0, bucket.length);}

 

其他方法

    /*** 获取第curPlace位的数值** @param d* @param curPlace 从0开始* @return*/private static int getDigit(int d, int curPlace) {d = d / ((int) Math.pow(10, curPlace));return d % 10;}/*** 获取元数据的位数** @param data* @return*/private static int getPlace(int[] data) {//null值或者长度为0if (data == null || data.length < 1) {return 0;}if (data.length == 1) {return String.format("%d", data[0]).length();}int[] mx = getMaxAndMin(data);//最大值的绝对值int max = Math.abs(mx[0]);//最小值的绝对值int min = Math.abs(mx[1]);//最大值的绝对值的十进制位数max = String.format("%d", max).length();//最小值的绝对值的十进制位数min = String.format("%d", min).length();return Math.max(max, min);//最大位数
    }/*** 获取最大和最小值** @param data* @return*/public static int[] getMaxAndMin(int[] data) {int[] mx = {Integer.MIN_VALUE, Integer.MAX_VALUE};for (int d : data) {if (mx[0] < d) {mx[0] = d;} else if (mx[1] > d) {mx[1] = d;}}return mx;}
View Code

 

四、算法的复杂度

基数排序的算法复杂度,最好时间复杂度、最坏时间复杂度和平均时间复杂度都为O(d(n+r)),空间复杂度为O(n+r),是稳定的算法。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331432.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Spring中使用多个动态缓存

在第三篇有关Spring&#xff08;长时间&#xff09;的缓存管理器的文章中&#xff0c;我想通过展示如何配置多个动态创建缓存的缓存管理器来扩展前 两个 。 Spring具有CompositeCacheManager &#xff0c;从理论上讲&#xff0c;它应该允许使用多个缓存管理器。 它通过询问基础…

java数据库编程——元数据(metadata)+web 与企业应用中的连接管理

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 测试源代码均为原创&#xff0c; 旨在理解 java数据库编程——元数据&#xff08;metadata&#xff09;web 与企业应用中的连接管理 的基础知识 &#xff1b; 2&#xff09;for database co…

托管 非托管_如何在托管的Kubernetes上备份Neo4J

托管 非托管在下面的视频中&#xff0c;我将解释如何对在托管Kubernetes环境中运行的Neo4J实例进行完整和增量备份。 我们将使用其他Pod进行远程备份&#xff0c;并将备份数据存储在托管环境提供的持久卷上。 如果您想知道如何将Neo4J部署到托管Kubernetes&#xff0c;请查看以…

java国际化——Locale+数字格式

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 测试源代码均为原创&#xff0c; 旨在理解 java国际化——Locale数字格式 的基础知识 &#xff1b; 2&#xff09; java 编程语言是第一个设计成为全面支持国际化的语言。 2.1&#xff09;…

Linux指令类型(一)change指令

一、change指令 chattr chgrp chmod chown chfn chsh chroot 二、ch指令详细介绍 &#xff08;1&#xff09;chattr 全名&#xff1a;change attribute 作用&#xff1a;chattr命令用于改变文件属性 语法&#xff1a;chattr [-RV][-v<版本编号>]…

restful rest_HATEOAS的RESTful服务。 REST:刷新器

restful rest在这篇文章中&#xff0c;我们将介绍有关HATEOAS的RESTful服务的综合文章。 REST&#xff1a;刷新器。 1.简介 “不好了&#xff01; 请&#xff0c;不要再发表有关REST的文章&#xff01;” 你们中的许多人可能会尖叫&#xff0c;这是正确的。 已经出版了太多的…

Unicode® Character Name Index

【0】README 0.1&#xff09; there are unicodes for varients of alphabet a, for that of b, c, or d and so on, please visit http://unicode.org/charts/charindex.html [A] A WITH ACUTE, LATIN CAPITAL LETTER 00C1 A WITH ACUTE, LATIN SMALL LETTER 00E1 A WITH…

java8 hash算法

一、hash算法哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值&#xff0c;这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母&#xff0c;随后的哈希都将产生不同的值。要找到散列为同…

exchanger_如何通过示例在Java中使用Exchanger

exchanger大家好&#xff0c;如果您在并发Java应用程序中工作&#xff0c;那么您可能听说过java.util.concurrent包的Exchanger类。 Java中的Exchanger是Java 1.5中与CountDownLatch &#xff0c; CyclicBarrier和Semaphores一起引入的另一个并发或同步实用程序。 顾名思义&…

Java Enumeration接口与Iterator接口

一、Enumeration接口 Enumeration接口中定义了一些方法&#xff0c;通过这些方法可以枚举&#xff08;一次获得一个&#xff09;对象集合中的元素。 这种传统接口已被迭代器取代&#xff0c;虽然Enumeration 还未被遗弃&#xff0c;但在现在代码中已经被很少使用了。尽管如此&a…

java国际化——日期和时间+排序

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 测试源代码均为原创&#xff0c; 旨在理解 java国际化——日期和时间排序 的基础知识 &#xff1b; 【1】日期和时间 1&#xff09;当格式化日期和时间时&#xff0c;需要考虑4个与 Locale …

jvm 垃圾收集算法_JVM垃圾收集和优化

jvm 垃圾收集算法总览 在对系统进行性能相关问题的故障排除时&#xff0c;内存优化是一个需要深入分析每个系统在内存中存储的内容&#xff0c;存储时间和访问方式的场所。 这篇文章是要对背景信息进行注释&#xff0c;并在此工作中要注意一些要点&#xff0c;这些工作要针对基…

数据库SQL索引

一、索引的意义 表中创建索引&#xff0c;以便更加快速高效地查询数据。 用户无法看到索引&#xff0c;它们只能被用来加速搜索/查询。 注释&#xff1a;更新一个包含索引的表需要比更新一个没有索引的表花费更多的时间&#xff0c;这是由于索引本身也需要更新。因此&#x…

java国际化——消息格式化+文本文件和字符集

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 测试源代码均为原创&#xff0c; 旨在理解 java国际化——消息格式化文本文件和字符集 的基础知识 &#xff1b; 2&#xff09; 由于本文涉及到的源代码都比较简单&#xff0c;所以直接将全…

java 8 新功能详解_Java 8和Java 14之间的新功能

java 8 新功能详解从版本9开始&#xff0c;Java每6个月就有一次新功能&#xff0c;因此很难跟踪这些新更改。 互联网上的大多数信息都描述了最近2个Java版本之间的变化。 但是&#xff0c;如果您的情况与我相似&#xff0c;则说明您使用的不是Java的最新版本&#xff0c;而是使…

Tomcat配置虚拟内存

一、Tomcat启动参数JAVA_OPTS参数说明   -server 启用jdk 的 server 版&#xff1b;   -Xms java 虚拟机初始化时的堆最小内存&#xff1b;   -Xmx java 虚拟机可使用堆的最大内存&#xff1b;   -XX: PermSize 非堆内存永久保留区域   -XX:MaxPermS…

ISO语言代码和国家代码+Locale常量+ISO货币符号

【1】ISO语言代码和国家代码 【2】Locale常量 【3】ISO货币符号

djl和ljl_使用Spring Boot和DJL进行深度学习

djl和ljl总览 这是Spring Boot上的另一篇文章 &#xff0c;该文章将展示如何使用Deep Java Library &#xff08;DJL&#xff09;构建示例Web应用程序&#xff0c; Deep Java Library &#xff08;DJL&#xff09;是Java的开源深度学习库&#xff0c;用于诊断X射线图像上的COVI…

java BigDecimal八种舍入模式

一、BigDecimal介绍java.math.BigDecimal不可变的immutable、任意精度的有符号十进制数。BigDecimal 由任意精度的整数非标度值和32位的整数标度(scale)组成。标度(scale)如果为零或正数&#xff0c;则标度是小数点后的位数。如果为负数&#xff0c;则将该数的非标度值乘以10的…

java国际化——资源包

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 旨在理解 java国际化——资源包 的基础知识 &#xff1b; 2&#xff09; 本文源代码idea 转自&#xff1a; &#xff08;利用properties 文件进行国际化&#xff09;https://docs.oracle.co…