Hark的数据结构与算法练习之基数排序
算法说明
基数排序是基于计数排序的,所以看这个之前要先看一下计数排序对于理解基数排序是很有帮助的(发现计数和基数的音节几乎一致啊)。这个我有写,请点击。
OK,现在你肯定已经熟悉了计数排序,那么我就来说一下基数排序。
所谓基数排序,其实就是分别对数字的个位,十位,百位,百位。。。。分别进行计数排序。
当然可以从个位往上进行计数排序,也可以从高位往个数计数排序,这里我们使用个位往上计数排序的方法。
话说,我想了好半天,不知道从哪里入手说基排(鸡排,哈哈)的思路……好蛋疼
这样,先从与计数排序的区别说起吧,区别在于计数排序是直接对数字进行排序。而基数排序是分别对个位,十位,百位。。。进行排序的。
然后,每个位数中,都有0至9共10个数字(即个数时,其实就是10个数字做排序;十数时,其实也是对10个数字做排序),接着我们对每个数字中的数字进行计数排序(好绕口,意思就是说,当进行个数排序时,个位为1时,所以个位为1的数字进行计排,例如11,21,31,221,411等等)。
所以我们申请的是二维数组int[][] radixBucket = new int[10][length]; (代码27行) 第一维的10存储的就是我们每次都是对10个数分别进行计排。第二维存储的就是对应的要排序的数字啦
同时,因为我们要保证数字的稳定性,当我们把低位的数字进行计排后,要把低位数字输出至原始数组中,然后再进行高位排序。
OK,解释到现在不知道有没有说清楚了。。。我发现我语言表达能力还真的是很差劲啊。
我觉得看代码可能会更清楚些,代码上也有注释,代码如下:
代码
使用的是java
/*
* 基数排序
*/
public class RadixSort {
public static void main(String[] args) {
int[] arrayData = { 2, 3, 1, 5, 6, 7, 4, 65, 42 };
RadixSortMethod(arrayData, 100);
for (int integer : arrayData) {
System.out.print(integer);
System.out.print(" ");
}
} /*
* arrayData - 要排序的数据 height - 要排序的步长 如果100,则只排序个位十位
*/
public static void RadixSortMethod(int[] arrayData, int height) {
int maxNum = 0; // 最大值,用于存储桶数据临时数组空间大小
for (int data : arrayData) {
if (data > maxNum) {
maxNum = data;
}
} int step = 1;
int length = arrayData.length;
int[][] radixBucket = new int[10][length]; // 二维数组,排序的容器
int[] arrayTemp = new int[maxNum + 1]; // 这个是每个桶中的数字个数
int num;
int index = 0;
while (step < height) {
for (int data : arrayData) {
// 当step=1时统计个数,这时取出个位的数字。
// 当step=10时,统计十数,这时取出十位的数字
num = data / step % 10;
radixBucket[num][arrayTemp[num]] = data;
arrayTemp[num]++;
} for (int i = 0; i < 10; i++) {
if (arrayTemp.length > i && arrayTemp[i] != 0) {
for (int j = 0; j < arrayTemp[i]; j++) {
arrayData[index] = radixBucket[i][j];
index++;
}
arrayTemp[i] = 0; // 将当前数字个数重置为0,用于下次的统计
}
} step *= 10;
index = 0;
}
}
}
结果
1 2 3 4 5 6 7 42 65
时间复杂度:
假设步长是s,待排序数组长度是n,数字最大值是m
那么时间复杂度就是O(s(n+(10*m)))=O(s(m+n))
空间复杂度:
待排序数组长度是n,数字最大值是m。
那么空间复杂度就是O(10*n+(m+1))=O(m+n)
稳定性:是稳定的
应用场景:
针对最大值相对比较小的正整数。
Hark的数据结构与算法练习之基数排序的更多相关文章
- Hark的数据结构与算法练习之若领图排序ProxymapSort
算法说明 若领图排序是分布排序的一种. 个人理解,若领图排序算是桶排序+计数排序的变异版,桶排序计数排序理解了,那么若领图排序理解起来就会比较容易.区别其实就是存储中间值的方式做了调整…… 话说,这个 ...
- Hark的数据结构与算法练习之珠排序
---恢复内容开始--- 算法说明 珠排序是分布排序的一种. 说实在的,这个排序看起来特别的巧妙,同时也特别好理解,不过不太容易写成代码,哈哈. 这里其实分析的特别好了,我就不画蛇添足啦. 大家看一 ...
- Hark的数据结构与算法练习之鸽巢排序
算法说明 鸽巢排序是分布排序的一种,我理解其实鸽巢就是计数排序的简化版,不同之处就是鸽巢是不稳定的,计数排序是稳定的. 逻辑很简单,就是先找出待排数组的最大值maxNum,然后实例一个maxNum+1 ...
- Hark的数据结构与算法练习之锦标赛排序
算法说明 锦标赛排序是选择排序的一种. 实际上堆排序是锦标赛排序的优化版本,它们时间复杂度都是O(nlog2n),不同之处是堆排序的空间复杂度(O(1))远远低于锦标赛的空间复杂度(O(2n-1)) ...
- Hark的数据结构与算法练习之圈排序
算法说明 圈排序是选择排序的一种.其实感觉和快排有一点点像,但根本不同之处就是丫的移动的是当前数字,而不像快排一样移动的是其它数字.根据比较移动到不需要移动时,就代表一圈结束.最终要进行n-1圈的比较 ...
- Hark的数据结构与算法练习之梳排序
算法说明梳排序是交换排序的一种,它其实也是改自冒泡排序,不同之处是冒泡排序的比较步长恒定为1,而梳排序的比较步长是变化的. 步长需要循环以数组长度除以1.3,到最后大于等于1即可. 光说可能比较抽象, ...
- Hark的数据结构与算法练习之地精(侏儒)排序
算法说明 地精排序是交换排序的一种,它是冒泡排序的一种改良,我感觉和鸡尾酒排序挺像的. 不同之处是鸡尾酒排序是从小到大,然后再从大到小切换着排序的.而地精排序是上来先从小到大排序,碰到交换到再从大到小 ...
- Hark的数据结构与算法练习之Bogo排序
算法说明 Bogo排序是交换排序的一种,它是一种随机排序,也是一种没有使用意义的排序,同样也是一种我觉得很好玩的排序. 举个形象的例子,你手头有一副乱序的扑克牌,然后往天上不停的扔,那么有一定机率会变 ...
- Hark的数据结构与算法练习之臭皮匠排序
算法说明 个人感觉是没有意义的算法,只是用来作为学术研究.或者说开拓一下思维. 从wikipedia copy来的一句解释的话:Stooge排序是一种低效的递归排序算法,甚至慢于冒泡排序.在<算 ...
随机推荐
- Android Activity模拟dialog
Android项目中很多地方,都会弹出一个弹出框.类似于自己定义的alertDialog,比如微信的退出提示,但由于Dialog的限制,可能不能很完美的实现你的想要的功能,所有研究发现他们这种实现其实 ...
- ■Ascii逐字解码法注入,mysql5.0一下版本手工注入
/*By:珍惜少年时*/ 逐字解码法,不一定非要猜字段内容.库名,表名,字段,data,都能猜. 环境过滤了select.union(mysql5.0以下的版本就不支持union所以也可以用此方法), ...
- C#结构体和类的区别
1.不能在结构体中定义默认构造方法: 2.在结构体中的非默认构造方法中,必须对结构体中所有的字段进行初始化,否则将报错. 3.在类中声明字段的同时,可以初始化,字段的值.在结构体中不可以. 4.结构体 ...
- maven常见问题
maven常见错误: 一..在Eclipse导入已存在工作空间的项目,出现 情况1: Scanning errors (1):1 Could not read pom.xml 就是pom.xml出现了 ...
- POJ 1062 昂贵的聘礼
C - 昂贵的聘礼 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit St ...
- [ruby on rails] 跟我学之(8)修改数据
修改views 修改index视图(app/views/posts/index.html.erb),添加编辑链接,如下: <h1>Our blogs</h1> <% @p ...
- c# 如何使用wlanapi连接电脑到wifi
http://www.codeproject.com/Articles/72105/Manage-WiFi-with-Native-API-WIFI-on-Windows-XP-SP Introduc ...
- STM32canopen调试
问题1:用usbcan监测不到can口的报文 属于接线问题 CANopen程序总使用的是can1 对应的接下口在J1的1和2口,而其接口排序是从外向里排序,故最外面的为1号接口,由于接线时,按照左边的 ...
- object-c面向对象2
我们知道在c#中有访问私有成员变量的get 和set方法.这个目的是用来公开实力对象的私有变量.我看了下ios的访问修饰符.也就是private,public,protected.这些基本上都和c# ...
- 如何分割一个utf8字符串(保证单个汉字的完整性)
std::list<std::string> split_utf8_string(const std::string& text) { std::list<std::stri ...