排序之基数排序

基数排序也是一种不基于比较的排序方法,它的思想是这样的:假设有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)

原文地址:https://www.cnblogs.com/codeMedita/p/7422363.html