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

基数排序针对的待排序元素是要有高低位之分的,比如单词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. PAT——1065. 单身狗

    “单身狗”是中文对于单身人士的一种爱称.本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱. 输入格式: 输入第一行给出一个正整数N(<=50000),是已知夫妻/伴侣的对数:随后N行 ...

  2. PAT——1022. D进制的A+B

    输入两个非负10进制整数A和B(<=230-1),输出A+B的D (1 < D <= 10)进制数. 输入格式: 输入在一行中依次给出3个整数A.B和D. 输出格式: 输出A+B的D ...

  3. Luogu[P1108] 低价购买

    \(Link\) \(\mathcal{\color{red}{Description}}\) 请你求出一个数列的最长下降子序列长度,并为此求出其方案数. \[1 \leq N \leq 5000\] ...

  4. HDU 1050(楼道搬桌子问题)(不是贪心解法,思路很新颖)

    Moving Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  5. FCC Truncate a string 解决方法

    三行搞定 function truncate(str, num) { ab = str.length >num?num>3?str.slice(0,num-3)+ "...&qu ...

  6. Python 学习笔记(十二)Python文件和迭代(二)

    迭代 基本含义 迭代是重复反馈过程的活动,其目的通常是为了接近并到达所需的目标或结果.每一次对过程的重复被称为一次“迭代”,而每一次迭代得到的结果会被用来作为下一次迭代的初始值.  在计算科学中,迭代 ...

  7. mongodb分组函数的使用(spring-data-mongodb)

    这两天要做mongodb日志的模块,下面记录一下. 一. 首先要导入一批数据,使用springboot来完成. 配置mongodb的复制集:在application.yml文件中配置uri来完成 格式 ...

  8. python3>日期和时间

    阅读目录 1.python3日期和时间 2.时间元组 3.获取格式化的时间 4.格式化日期 5.获取月日历 6.Time模块 7.datetime模块 回到顶部 1.python3日期和时间 Pyth ...

  9. 前端使用mobx时,变量已经修改了,为什么组件还是没变化,map类型变量,对象类型变量的值获取问题(主要矛盾发生在组件使用时)

    前天我在使用一个前端多选框组件时遇到了一个问题,明明对象内的值已经修改了,但是组件显示的还是没有效果改变,以下是当时打出的log,我打印了这个对象的信息 对象内的值已经修改了但是组件还是不能及时更改, ...

  10. 解决placeholder对ie9及以下的不兼容

    具体的看代码,都写在注释里了,欢迎讨论 <script> $(function () { /* *页面加载立刻执行 *@method:each遍历每个包含placeholder属性的对象( ...