基数排序也是一种不基于比较的排序方法,它的思想是这样的:假设有m个数据,先根据个位数大小对这m个数据进行排序,得到一个新的序列;然后根据十位数大小对这m个数据进行排序,又得到一个新的序列;然后再根据百位、千位,依次类推,直至最高位,最后得到的序列就是有序的序列。那么对每一位的排序是如何进行的呢?位排序的思想是这样的:假设每位数据的范围是0到9,那么就创建10个桶(可用数组表示),如果该位数是0,那么就放到0号桶内,是1就放到1号桶内.....,最后从0号桶到9号桶,依次取出桶内的数据,就可以得到一个序列,这里同一个桶内的数据顺序任意,处于同一个桶内的数据,说明它们这一位的数是相同的。先用图示举一个例子:
基数排序的算法描述如下:
radix_sort(A,d)//1是最低位,d是最高位
1、for i=1 to d
2、 do use a stable sort to sort array A on digit i
算法描述很简单,但是里面的细节还是挺多的,首先,我们要创建桶,这里桶是用一个数组表示,桶内元素类型是一个自定义的类,类可以存储数组A中的数据,而为了取“位”的方便,这里将数组A中的数据均用String类型表示,对图中序列进行基数排序的代码示例图下:
class stableNode{ String val=null; stableNode next=null; public stableNode(String val){ this.val=val; } } public class Test{ public static void main(String[] args)throws InterruptedException{ String[] value={"329","457","657","839","436","720","355"}; radix_sort(value); System.out.println(); } static void radix_sort(String[] value){ //创建一个盒子,用于存放数据 stableNode[] stable=new stableNode[10];//0 to 9 int i=0; //因为要从最低位开始排序,所以要对数据进行翻转,使其高低位交换位置 for(i=0;i<value.length;i++){ value[i]=(new StringBuilder(value[i]).reverse()).toString(); } for(String str:value){ System.out.print(str+" "); } System.out.println(); //注意这里,为了演示方便,将所有数据的位数都设成一样的 int maxLen=value[0].length(); int index=0; int k=0; for(k=0;k<maxLen;k++){//进行数字位的遍历 for(i=0;i<value.length;i++){//遍历待排序的数组 //为了演示方便,这里假定所有数据的位数是相同的!!! //也就是说,如果是百位数,那么全是百位数 //如果数的位数不同,则需要进一步修改排序细节,但是思想是相同的 index=Integer.valueOf(value[i].substring(k,k+1)); build_stable(stable,index,value[i]); } sort_result(stable,value); } for(i=0;i<value.length;i++){ value[i]=(new StringBuilder(value[i]).reverse()).toString(); } for(String str:value){ System.out.print(str+" "); } } //将桶内的数据从新放到数组里面,从而得到一个新的序列 static void sort_result(stableNode[] stable,String[] value){ int k=0,i=0; stableNode root=null; for(i=0;i<stable.length;i++){//其实是i<10即可 root=stable[i]; while(root!=null){ value[k++]=root.val; root=root.next; } } //全部赋值为空,以待下次使用 for(i=0;i<stable.length;i++){ stable[i]=null; } } //创建桶,根据基数,将数据放到何时的桶里面 static void build_stable(stableNode[] stable,int index,String value){ if(stable[index]==null){ stable[index]=new stableNode(value); }else{ stableNode list=stable[index]; while(list.next!=null){ list=list.next; } list.next=new stableNode(value); } } static void printArray(int[] array){ for(int val:array){ System.out.print(val+" "); } System.out.println(); } }
基数排序分析:时间复杂度是O(max_digit*(radix_size+n)),其中max_digit是每位中的最大数值,在这里是9,radix_size是0到k之间的k中可能取值这里是0到9共10中可能取值。由于需要建立桶,且要盛放序列A中的所有数据,所以空间复杂度是O(n)