zoukankan      html  css  js  c++  java
  • 排序之基数排序

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

  • 相关阅读:
    随笔一篇
    WPF SDK研究 Intro(2) QuickStart2
    WPF SDK研究 Intro(1) QuickStart1
    两道MS的面试题 及答案
    关于父子类方法的继承
    WCF笔记 1.WCF基础
    Vista下建立WCF遇到的问题及解决方案
    WPF SDK研究 目录
    WPF SDK研究 Printing (1) PrintDialog
    WPF SDK研究 Printing (2) EnumerateSubsetOfPrintQueues
  • 原文地址:https://www.cnblogs.com/codeMedita/p/7422363.html
Copyright © 2011-2022 走看看