基数排序算是桶排序和计数排序的衍生吧,因为基数排序里面会用到这两种其中一种。

基数排序针对的待排序元素是要有高低位之分的,比如单词adobe,activiti,activiti就高于adobe,这个是根据ascll码来的。

现在我们可以提出一个问题,怎样对字典里面的单词进行排序呢?

比如我们现在有如下单词:

"Java", "Mongodb", "Redis", "Kafka", "javascript", "mysql", "mybatis", "kindle", 
"rpc", "Algorithm", "mergeSort", "quickSort", "Adobe"

我们要怎么对它排序呢,这里就可以用到基数排序了,基数排序的原理就是我们将一个元素按高低位分成单个个体,比如Adobe我们

就分成A,d,o,b,e,Algorithm我们就分成A,l,g,o,r,i,t,h,m,然后我们从右往左,依次比较即可。

但是这里Adobe和Algorithm并不能直接比较,因为他们的长短不一,所以在比较之前我们应该找到最长的元素的长度,然后将其余短的元素补全

到一样长:

Adobe0000

Algorithm

这样才可以形成比较,从右往左,0:m,0:h,0:t,0:i,e:r,b:o,o:g,d:l,A:A,我们就可以比较出来Adobe > Algorihtm

跟着以下的图片会更清楚原理:

从上图我们可以看出,基数排序会从右往左依次比较(即在我们的程序实现里面需要遍历很多次),而具体要遍历多少次则取决于最长的元素有多长,从右往左对每个位
的元素比较可以用到桶排序或计数排序,桶排序和计数排序的时间复杂度都是O(n),假设最大的元素长度为K,则基数排序的时间复杂度为O(k * n),而k一般不会有多大,
可以视为常量,所以基数排序的时间复杂度也是O(n)。 以下是我的Java实现:
 package com.structure.sort;

 /**
* @author zhangxingrui
* @create 2019-01-30 14:58
**/
public class RadixSort { public static void main(String[] args) {
/*int[] numbers = {19, 36, 24, 10, 9, 29, 1, 0, 3, 60, 100, 1001, 999, 520, 123, 96};
radixSort(numbers);
for (int number : numbers) {
System.out.println(number);
}*/ String[] words = {"Java", "Mongodb", "Redis", "Kafka", "javascript", "mysql", "mybatis", "kindle", "rpc", "Algorithm", "mergeSort", "quickSort", "Adobe"};
// String[] words = {"Java", "mongodb", "Kafka"};
radixSort(words);
for (String word : words) {
System.out.println(word.replaceAll("0", ""));
}
} /**
* @Author: xingrui
* @Description: 基数排序(单词)
* @Date: 15:53 2019/1/30
*/
private static void radixSort(String[] words){
int exp = 0;
int maxLength = getMaxLength(words);
autoComplete(words, maxLength);
for(exp = 1; exp <= maxLength; exp++){
countingSort(words, exp);
}
} /**
* @Author: xingrui
* @Description: 计数排序(单词)
* @Date: 13:57 2019/1/30
*/
private static void countingSort(String[] words, int exp){
int n = words.length;
String[] r = new String[n];
int[] c = new int[122]; for(int i = 0; i < n; ++i){
int asc = (byte)words[i].charAt(words[i].length() - exp);
c[asc]++;
} for(int i = 1; i < 122; ++i){
c[i] = c[i-1] + c[i];
} for (int i = n - 1; i >= 0; --i){
int asc = (byte)words[i].charAt(words[i].length() - exp);
int index = c[asc];
r[index - 1] = words[i];
c[asc]--;
} for(int i = 0; i < n; ++i){
words[i] = r[i];
}
} /**
* @Author: xingrui
* @Description: 基数排序(纯数字)
* @Date: 15:00 2019/1/30
*/
private static void radixSort(int[] numbers){
int exp = 0;
int maxNumber = getMaxNumber(numbers);
for(exp = 1; maxNumber/exp > 0; exp *= 10){
countingSort(numbers, exp);
}
} /**
* @Author: xingrui
* @Description: 计数排序(纯数字)
* @Date: 13:57 2019/1/30
*/
private static void countingSort(int[] numbers, int exp){
int n = numbers.length; int[] r = new int[n];
int[] c = new int[10]; for(int i = 0; i < n; ++i){
c[numbers[i]/exp % 10]++;
} for(int i = 1; i < 10; ++i){
c[i] = c[i-1] + c[i];
} for (int i = n - 1; i >= 0; --i){
int index = c[numbers[i] / exp % 10];
r[index - 1] = numbers[i];
c[numbers[i] / exp % 10]--;
} for(int i = 0; i < n; ++i){
numbers[i] = r[i];
}
} /**
* @Author: xingrui
* @Description: 自动补全单词
* @Date: 16:38 2019/1/30
*/
private static void autoComplete(String[] words, int maxLength){
int i = 0;
for (String word : words) {
if(word.length() < maxLength){
int value = maxLength - word.length();
StringBuilder sb = new StringBuilder();
for(int j = 0; j < value; ++j){
sb.append("0");
}
words[i] = word + sb;
}
i++;
}
} /**
* @Author: xingrui
* @Description: 获取字符串最大的长度
* @Date: 15:56 2019/1/30
*/
private static int getMaxLength(String[] words){
int maxLength = words[0].length();
for(int i = 1; i < words.length; ++i){
if(words[i].length() > maxLength)
maxLength = words[i].length();
}
return maxLength;
} /**
* @Author: xingrui
* @Description: 获取最大的数字
* @Date: 15:56 2019/1/30
*/
private static int getMaxNumber(int[] numbers){
int maxNumber = numbers[0];
for(int i = 1; i < numbers.length; ++i){
if(numbers[i] > maxNumber)
maxNumber = numbers[i];
}
return maxNumber;
} }

其中需要注意就是在排序之前需要找到最大的元素长度以确定循环次数和根据最大元素长度补全比较短的元素。

程序执行结果:

需要特别说明的是,文中的图片均截图极客网王争老师的专栏《数据结构与算法之美》,如有侵权,请联系我删除。

有需要的朋友也可以去订阅这个专栏,讲的挺不错的,没有视频,只有文字和音频。

小白初识 - 基数排序(RadixSort)的更多相关文章

  1. 基数排序(RadixSort)

    1 基数排序的特点是研究多个关键字key,且多个key之间有权重之分,    或者可把单个key建模为含有多个key的排序 而计数排序.桶排序始终只有个一个key,或者说围绕着一个比较规则 Ex:比较 ...

  2. 小白初识 - 计数排序(CountingSort)

    计数排序,属于桶排序特殊的一种. 当要排序n个数据的时候,如果所处的范围不大,我们可以取其中的最大值K,并将数据分散在K个桶里面, 每个桶里面的数据都是相同的(这样省去了桶内排序的时间),然后顺序取出 ...

  3. 小白初识 - 快速排序(QuickSort)

    我个人觉得快速排序和归并排序有相似之处,都是用到了分治的思想,将大问题拆分成若干个小问题. 不同的地方是归并排序是先把大问题拆分好了之后再排序,而快速排序则是一边拆分,一边排序. 快速排序的原理就是, ...

  4. 小白初识 - 归并排序(MergeSort)

    归并排序是一种典型的用分治的思想解决问题的排序方式. 它的原理就是:将一个数组从中间分成两半,对分开的两半再分成两半,直到最终分到最小的单位(即单个元素)的时候, 将已经分开的数据两两合并,并且在合并 ...

  5. 排序算法----基数排序(RadixSort(L))单链表智能版本

    转载http://blog.csdn.net/Shayabean_/article/details/44885917博客 先说说基数排序的思想: 基数排序是非比较型的排序算法,其原理是将整数按位数切割 ...

  6. 排序算法----基数排序(RadixSort(L,max))单链表版本

    转载http://blog.csdn.net/Shayabean_/article/details/44885917博客 先说说基数排序的思想: 基数排序是非比较型的排序算法,其原理是将整数按位数切割 ...

  7. 模板化的七种排序算法,适用于T* vector<T>以及list<T>

    最近在写一些数据结构以及算法相关的代码,比如常用排序算法以及具有启发能力的智能算法.为了能够让写下的代码下次还能够被复用,直接将代码编写成类模板成员函数的方式,之所以没有将这种方式改成更方便的函数模板 ...

  8. 6种基础排序算法java源码+图文解析[面试宝典]

    一.概述 作为一个合格的程序员,算法是必备技能,特此总结6大基础算法.java版强烈推荐<算法第四版>非常适合入手,所有算法网上可以找到源码下载. PS:本文讲解算法分三步:1.思想2.图 ...

  9. 20172328 2018-2019《Java软件结构与数据结构》第五周学习总结

    20172328 2018-2019<Java软件结构与数据结构>第五周学习总结 概述 Generalization 本周学习了第九章:排序与查找,主要包括线性查找和二分查找算法和几种排序 ...

随机推荐

  1. MRC 和 ARC 混编

    在targets的build phases选项下Compile Sources下选择要不使用arc编译的文件,双击它,输入 -fno-objc-arc 即可   MRC工程中也可以使用ARC的类.方法 ...

  2. .net core API 使用swagger

    第一种方法:直接添加swagger,会在app_start中生成SwaggerConfig,在该文件中配置相关内容(把生成xml打开): 第二种方法:添加四个引用文件Swashbuckle.AspNe ...

  3. import 本质

    一. 模块:用来从逻辑上来组织python代码(变量,函数,类,逻辑,实现一个功能),本质就是,py结尾的python文件 1.1 导入方法: import module import module1 ...

  4. 【js】javaScript 执行机制

    javascript 是一门单线程语言(按照语句一行一行的执行) let a = '1'; console.log(a); let b = '2'; console.log(b); 这样子正常执行是没 ...

  5. eclipse的git插件安装、配置与使用

    Git是一个分布式的版本控制工具,本篇文章从介绍Git开始,重点在于介绍Git的基本命令和使用技巧,让你尝试使用Git的同时,体验到原来一个版 本控制工具可以对开发产生如此之多的影响,文章分为两部分, ...

  6. MySQL常用:Got a packet bigger than 'max_allowed_packet' bytes & MySQL开远程服务

    1. 数据导入时出现错误 Got a packet bigger than 'max_allowed_packet' bytes 通过终端进入mysql控制台 mysql>show VARIAB ...

  7. Java 常见BUG 整理

    1.BigDecimal初始化double 2.Integer   java对于-128到127之间的数,会进行缓存,这个范围的Integer对象是同一个! == 是ok,但是超出这个范围就不可以用 ...

  8. C++11 initializer_list 和 Range-based for loop 学习理解

    win10 + vs2017 源码如下: int main() { vector< int > numbers = { 1, 2, 3, 4, 5 }; for (auto num : n ...

  9. HCNA(二)以太网的帧结构

    一.网络通讯协议 一般地,关注于逻辑数据关系的协议通常被称为上层协议,而关注于物理数据流的协议通常被称为低层协议. IEEE802就是一套用来管理物理数据流在局域网中传输的标准,包括在局域网中传输物理 ...

  10. HBase的详细安装部署

    一.部署 1.Zookeeper正常部署,并且启动 2.Hadoop正常部署,并且启动 3.Hbase的解压 解压HBase到指定目录 tar -xvf  /HBase.tar.gz -C /airP ...