基数排序
基数排序
算法思想
基数排序不基于比较和移动,而是基于关键字的大小进行排序。
基数排序通常有最高位优先与最低为优先两种实现方法。
主要思想为:按照关键字的权重大小依次进行排序,最后形成一个有序序列。
实现思路
-
取到数组中的最大值,计算出它的位数,设为n(它的位数就是最外层循环的次数)
-
如何计算位数 n ?
规律如下:
System.out.println("个位为: " + 9876 / 1 % 10); System.out.println("十位为" + 9876 / 10 % 10); System.out.println("百位为" + 9876 / 100 % 10); System.out.println("千位为" + 9876 / 1000 % 10); System.out.println("万位为" + 9876 / 10000 % 10);
-
-
创建十个空队列(每1位数字最大可表示0-9共十位数字,所以要十个)
- 队列也是数据结构的一种,在此就不另行提供啦,我用的是自己写的链队列。
-
设外层循环进度为 i (循环进行到了第 i 次, i >= 1),当前进行到了第 i 次最外层循环,则将有序列表中的每个元素第 i 位(个位为1,十位为2,百位为3...以此类推)放入 i 的值所对应的队列中
- 举例:(比如2021,第一次循环时,它的个位为1,所以将它放在queue[1]中,第三次循环时,它的百位为0,所以将它放在queue[0]中....)
-
一次外层循环结束后,从队列0开始依次将元素出队,放入原先的数组中
- 队列先进先出,所以第0(从0开始计数)个队列的第1(从1开始计数)个元素就放在数组下标为0的位置上,以此类推,一个队列空换下一个队列,直到全部队列都出队完成。
-
如此重复n次,你就会发现神奇的一件事情——数组竟然有序啦!
实现代码
public static void RadixSort(int[] arr){
for(int i =0 ; i < arr.length; i++){
if(arr[i] <= 0){ // 基数排序要求队列中的数必须为正整数
System.out.println("sorry, you can't have negative number.");
System.out.println("抱歉,数组中不能存在非正整数。");
return ;
}
}
int max = Util.getMax(arr); // 获取数组中最大值的一个方法,引用自自己写的类。
int n = 0;
while (max > 0){
n++;
max /= 10;
}
Queue[] queue = new LinkQueue[10]; // This is also mine class that I code.
for(int i = 0; i < queue.length; i++){
queue[i] = new LinkQueue();
}
for(int i = 1; i <= n; i++){
int m = 1;
for(int h = 1; h < i; h++){
m *= 10;
}
for(int j = 0; j < arr.length; j++){
int k = arr[j] / m % 10;
queue[k].enQueue(arr[j]);
}
for(int l = 0, q = 0; l < queue.length; l++){
while (!queue[l].empty()){
arr[q++] = (Integer) queue[l].delQueue();
}
}
}
}
其它结论
基数排序也属于稳定排序;
基数排序的空间复杂度为O(r)【r个队列:r个队头指针和r个队尾指针】,时间复杂度为O(d(n+r))。