持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第23天,点击查看活动详情
1.什么是基数排序
基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。
2。实现基数排序时产生的疑问
- 如何自动识别最大数有几位(有几位就要识别几轮个位十位百位三轮)。
- 如何给二维数组扩容?
- 这个能排序负数吗?负数是否应该都先进行取绝对值,或者负数摘出来统一加绝对值后代进正数实现函数里面,然后再倒着输出。
想到一个方法:先调用大顶堆算法,找出最大的数,获取这个数有多少位。
扩容的话用一个一维数组记录每一个基数下面有多少个数
3.实现思路
- 步骤1:找出最大值,得到基数排序需要几轮,比如1905每次都除以10,直到小于10再给加一轮[1905每次要取的数不同,比如取千位1的时候前三次都只进行num/10运算,第四次才num%10取余]。
- 步骤2:先取个位,相同个位放在相同的桶里面,顺序放进就行记录每个桶里面有多少数。(桶的话直接创建一个类得了,反正也是固定只需要0-9,数目确定)|除以10等于0那就早些入桶[要让早些入桶没问题,不过要记录目前的次数不是最后一次并且num等于0]
4.代码实现
package sorting;
import java.util.Arrays;
/**
* 工具类
* @author Mr.AZU
*
*/
public class getNumArrayUtils {
private getNumArrayUtils() {}
/**
* 获取随机数组,每个数都是1000以内
* @param length 所要的数组长度
* @return
*/
static int[] getNumArray(int length) {
int[] numArray = new int[length];
for (int i = 0; i < length; i++) {
numArray[i] = (int)(Math.random()*1000);
}
return numArray;
}
/**
* 打印一维数组,适合数比较多的
* @param numArray
*/
static void printIt(int []numArray) {
for (int i = 0; i < numArray.length; i++) {
System.out.print(numArray[i]+",");
if (i%9==0&&i!=0) {
System.out.println();
}
}
}
/**
* 用Arrays打印一维数组,适合数比较少的
* @param numArray
*/
static void printItByA(int[] numArray) {
System.out.println(Arrays.toString(numArray));
}
/**
* 打印二维数组
* @param numArray
*/
static void printTarray(int[][] numArray) {
for (int[] is : numArray) {
System.out.println(Arrays.toString(is));
}
}
}
5.总结
【注意】1. 桶内不需要排序,只要按照多轮基数,从左到右从上到下的顺序取数 2. 最后一轮才是%10取余数,在那之前都是除以10 3. 复杂问题更要好好对下标 4. 每一轮都得把数组更新然后把桶清空
【不足】想法大致方向上是没问题的,也能实现,但是在入桶部分的下标问题上没有细心一一对好,应该在每个涉及下标的复杂句子后面加上备注,边备注边想下标逻辑对不对得上