package jxau.blueDot.lyx; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * * @author lyx * @下午2:15:41 * @TODO: * 基数排序——多关键字排序 * 多关键字排序的思路是将待排数据里德排序关键字拆分成多个排序关键字; * 第1个排序关键字,第2个排序关键字,第3个排序关键字...然后,根据子关键 * 字对待排序数据进行排序。 * * 多关键字排序时有两种解决方案: *(1)最高位优先法(MSD)(Most Significant Digit first) *(2)最低位优先法(LSD)(Least Significant Digit first) * * 例如,对如下数据序列进行排序。 * 192,221,12,23 * 可以观察到它的每个数据至多只有3位,因此可以将每个数据拆分成3个关键字: * 百位(高位)、十位、个位(低位)。 * 如果按照习惯思维,会先比较百位,百位大的数据大,百位相同的再比较十位, *十位大的数据大;最后再比较个位。人得习惯思维是最高位优先方式。如果按照人 *得思维方式,计算机实现起来有一定的困难,当开始比较十位时,程序还需要判断 *它们的百位是否相同--这就认为地增加了难度,计算机通常会选择最低位优先法。 * 基数排序方法对任一子关键字排序时必须借助于另一种排序方法,而且这种排序方法必须是稳定的。 *对于多关键字拆分出来的子关键字,它们一定位于0-9这个可枚举的范围内,这个范围不大,因此用桶式排序效率非常好。 *对于多关键字排序来说,程序将待排数据拆分成多个子关键字后,对子关键字排序既可以使用桶式排序,也可以使用任何一种稳定的排序方法。 */ /** * * 基数排序是一种当关键字为整数类型时非常高效的排序方法。 * 基本思想是:设待排序的数据元素关键字是m位d进制整数(不足m位的关键字在高位补0) * 设置d个桶,令其编号分别为0,1,2.... d-1 * 首先,按关键字最低位的数值一次把各数据元素放到相应的桶中 * 然后,按照桶号从小到大和进入桶中数据元素的先后次序收集分配在各桶中的数据元素, * 这样就形成了数据元素集合的一个新的排列,此为一次基数排序。重复m次,就得到了排好序 * 的数据元素序列 * */ /** * 基数排序:要求进出桶中的数据元素序列满足先进先出的原则,桶实际上就是队列 * 队列分为顺序队列和链式队列。 */ //例子:基于顺序队列的实现方法 //数据为{710,342,045,686,006,841,429,134,068,264} /** * 一共10个桶 分别为0-9 * 第一次基数排序:(根据个位数划分) * 264 006 * 710 841 342 134 045 686 068 429 * 0 1 2 3 4 5 6 7 8 9 * * 第二次基数排序:(根据十位数划分) * 045 * 342 068 * 006 710 429 134 841 264 686 * 0 1 2 3 4 5 6 7 8 9 * * 第三次基数排序:(根据百位数划分) * * 068 * 045 * 006 134 264 342 429 682 710 841 * 0 1 2 3 4 5 6 7 8 9 * * 收集后的新序列: * 006 045 068 134 264 342 429 686 710 841 */ public class RadixSort { public static int[] asc( int[] array ){ int index = 1; // 最大数字位数(如100为3位数字,2000为4位数字) // 取得最大数字位数 for( int i = 0 ; i < array.length ; i++ ){ int length = Integer.toString(array[i]).length(); if( index < length ){ index = length; } } return sort( array , 0 , index); } /** * @param array 数组 * @param exponent 起始位数(代码中实际意义为:10的exponent次方。起始位数即为10的0次方,所以为个位) * @param index 最大数字位数(如100为3位数字,2000为4位数字) * @return */ private static int[] sort( int[] array , int exponent , int index){ int length = array.length; // 此处我选择用List,而不是int[n][n]的数组 List<List<Integer>> list = new ArrayList<List<Integer>>(); for( int i = 0 ; i < 10 ; i++ ){ list.add(new ArrayList<Integer>()); } // 按照各个位数排序统计 for( int i = 0 ; i < length ; i++ ){ int num = 0; String str = Integer.toString(array[i]); if( str.length() - exponent - 1 >= 0 ) num = Integer.parseInt(str.substring(str.length() - exponent - 1, str.length() - exponent)); list.get(num).add(array[i]); } // 串起桶中数据 for( int k = 0 , i = 0 ; i < list.size() ; i++ ){ for( int j = 0 ; j < list.get(i).size() ; j++ ){ array[ k++ ] = list.get(i).get(j); } } // 若还有更高位数,则按照下一位数进行排序 if( index == ++exponent ){ return array; }else{ return sort( array , exponent , index ); } } }
代码摘自别处,敬请谅解!