基数排序 (Radix Sort)
来源:互联网 发布:学单片机需要什么基础 编辑:程序博客网 时间:2024/05/08 07:08
算法原理
———————————————————————————————————
基数排序 (Radix Sort) 是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。
————
排序过程:将所有待比较数值(必须是正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序;然后从桶中倒出所有数,完成一次排序;依次迭代到高位,这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
————
基数排序法会使用到桶 (Bucket),顾名思义,通过将要比较的位(个位、十位、百位…),将要排序的元素分配至 0~9 个桶中,借以达到排序的作用,在某些时候,基数排序法的效率高于其它的比较性排序法。
————
注:基数排序要满足的条件<1>必须是正整数;<2>从低位开始判断,一直迭代到最高位;<3>采用稳定排序。
多关键字排序时有两种解决方案:
最高位优先法(MSD)(Most Significant Digit first)
最低位优先法(LSD)(Least Significant Digit first)
例如,对如下数据序列进行排序。
192,221,12,23
可以观察到它的每个数据至多只有3位,因此可以将每个数据拆分成3个关键字:百位(高位)、十位、个位(低位)。
如果按照习惯思维,会先比较百位,百位大的数据大,百位相同的再比较十位,十位大的数据大;最后再比较个位。人得习惯思维是最高位优先方式。
如果按照人得思维方式,计算机实现起来有一定的困难,当开始比较十位时,程序还需要判断它们的百位是否相同–这就认为地增加了难度,计算机通常会选择最低位优先法。
基数排序方法对任一子关键字排序时必须借助于另一种排序方法,而且这种排序方法必须是稳定的。
对于多关键字拆分出来的子关键字,它们一定位于0-9这个可枚举的范围内,这个范围不大,因此用桶式排序效率非常好。
对于多关键字排序来说,程序将待排数据拆分成多个子关键字后,对子关键字排序既可以使用桶式排序,也可以使用任何一种稳定的排序方法。
此处给出两种实现方法:
<1>采用计数排序来实现基数排序,上一篇中有去实现过计数排序的实现,个人感觉计数排序所选择的桶有可能太多,因为是对于待排序中的最大值和最小值的差距个桶,基数排序所选的桶则为0-9号桶,对于每一位都采用计数排序,则能排好每一位的数,然后利用基数排序从低位到高位的迭代就可以完成排序。从时间和空间上都有所提升。
package 排序;import java.util.Arrays;public class RadixSort { //基于计数排序的基数排序算法 private static void radixSort(int[] array,int radix, int distance) { //array为待排序数组 //radix,代表基数 //代表排序元素的位数 int length = array.length; int[] temp = new int[length];//用于暂存元素 int[] count = new int[radix];//用于计数排序 int divide = 1; for (int i = 0; i < distance; i++) { System.arraycopy(array, 0,temp, 0, length); Arrays.fill(count, 0); for (int j = 0; j < length; j++) { int tempKey = (temp[j]/divide)%radix; count[tempKey]++; } for (int j = 1; j < radix; j++) { count [j] = count[j] + count[j-1]; } //运用计数排序实现基数排序的重点在下面这个方法 for (int j = length - 1; j >= 0; j--) { //这个必须从后面算,因为count统计的是总数 int tempKey = (temp[j]/divide)%radix; count[tempKey]--; array[count[tempKey]] = temp[j]; } divide = divide * radix; } } /** * @param args */ public static void main(String[] args) { int[] array = {3,2,3,2,5,333,45566,2345678,78,990,12,432,56}; radixSort(array,10,7); for (int i = 0; i < array.length; i++) { System.out.print(" " + array[i]); } } }
<2>采用java提供的数据结构Arraylist和LinkedList来实现,具体实现过程中有解释
public static void radixSort(int[] arr) { if (arr == null || arr.length < 2) { return; } int negNum = 0; for (int i = 0; i < arr.length; i++) { //统计正负整数的个数 negNum += arr[i] < 0 ? 1 : 0; } int[] negArr = new int[negNum]; int[] posArr = new int[arr.length - negNum]; int negi = 0; int posi = 0; for (int i = 0; i < arr.length; i++) { if (arr[i] < 0) { negArr[negi++] = -arr[i]; } else { posArr[posi++] = arr[i]; } } radixSortForPositive(negArr); radixSortForPositive(posArr); int index = 0; for (int i = negArr.length - 1; i >= 0; i--) { arr[index++] = -negArr[i]; } for (int i = 0; i < posArr.length; i++) { arr[index++] = posArr[i]; } } public static void radixSortForPositive(int[] arr) { if (arr == null || arr.length < 2) { return; } /*这里的数据结构是,ArrayList中存放的是LinkedList,原因是对于每个桶中的元素要进行调整,所以采用LinkedList; 而对于桶与桶之间只需要进行访问操作,所以选取ArrayList。 对于需要快速插入,删除元素,应该使用LinkedList。 对于需要快速随机访问元素,应该使用ArrayList。*/ ArrayList<LinkedList<Integer>> qArr1 = new ArrayList<LinkedList<Integer>>(); ArrayList<LinkedList<Integer>> qArr2 = new ArrayList<LinkedList<Integer>>(); for (int i = 0; i < 10; i++) { qArr1.add(new LinkedList<Integer>()); qArr2.add(new LinkedList<Integer>()); } for (int i = 0; i < arr.length; i++) { //arr[i] % 10,得到对应的位上的数,get()找到对应的桶,offer()添加到对应的桶 qArr1.get(arr[i] % 10).offer(arr[i]); } long base = 10; while (base <= Integer.MAX_VALUE) { for (int i = 0; i < 10; i++) { //get()找到对应的桶 LinkedList<Integer> queue = qArr1.get(i); while (!queue.isEmpty()) { //倒桶 int value = queue.poll(); //按从低位到高位迭代 qArr2.get((int) (value / base) % 10).offer(value); } } ArrayList<LinkedList<Integer>> tmp = qArr1; qArr1 = qArr2; qArr2 = tmp; base *= 10; } int index = 0; for (int i = 0; i < 10; i++) { LinkedList<Integer> queue = qArr1.get(i); while (!queue.isEmpty()) { arr[index++] = queue.poll(); } } }
- Radix Sort 基数排序
- radix sort 基数排序
- 基数排序(Radix Sort)
- 基数排序 (Radix sort)
- 基数排序(radix sort)
- 基数排序(Radix Sort)
- 基数排序 (Radix Sort)
- Radix sort 基数排序
- 基数排序(Radix Sort)
- 基数排序 Radix Sort
- 基数排序-Radix sort
- 基数排序(RADIX SORT
- 基数排序(Radix Sort)
- 基数排序-Radix Sort
- (四)分配排序:基数排序(radix sort)
- 经典排序算法 - 基数排序Radix sort
- 经典排序算法 - 基数排序Radix sort
- 经典排序算法 - 基数排序Radix sort
- size_type详解
- centos安装ganglia
- 如何让别人信任你?
- php-fpm 与 Nginx优化总结
- Build.prop重要参数解释
- 基数排序 (Radix Sort)
- OC 关键字
- MongoDB 3.0 用户创建
- 任务调度开源框架Quartz动态添加、修改和删除定时任务
- [学习分享] 在Windows操作系统下如何安装RMySQL包
- O2O、C2C、B2B、B2C的区别在哪里?
- mysqld与mysqld_safe的区别
- enum类型
- 扣丁学堂——SharedPreferences