zoukankan      html  css  js  c++  java
  • java方式实现基数排序

    一、基数排序描述

      基数排序(radix sort)属于"分配式排序"(distribution sort),又称"桶子法"(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些"桶"中,藉以达到排序的作用,基数排序法是属于稳定性的排序。基数排序有二种实现方式:最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。最低位优先(Least Significant Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。

    二、基本思路

      基数排序采用最低优先的方式,将所有待排序数列元素统一为同样的数位长度,数列元素数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

    三、实现步骤

    1. 找到数列元素的个位数,然后以个位数为桶的索引,将数列元素存放在桶中。
    2. 遍历桶,将桶的数据元素取出依次存放在原数组中。
    3. 找到数列元素的高位数,重复1,2操作,直到找操作完最高位数,这时数列就有序了。

    四、案例分析

    以数组{6,5,7,3,1,12,33,53,25,89,108,149,44,87,36}为例:

    第一轮按个位数排序如下图:每一列为一个桶

    0 1 2 3 4 5 6 7 8 9
      1 12 3 44 5 6 7 108 89
          33   25 36 87   149
          53            

    按各位排序结果为:{1, 12, 3, 33, 53, 44, 5, 25, 6, 36, 7, 87, 108, 89, 149}

    第二轮按十位数排序如下图:每一列为一个桶

    0 1 2 3 4 5 6 7 8 9
     1 12 25 33 44 53     89  
     3     36 149     87    
    5                  
    6                  
    7                  
    108                  

    按十位排序结果为:{1, 3, 5, 6, 7, 108, 12, 25, 33, 36, 44, 149, 53, 87, 89}

    第三轮按百位数排序如下图:每一列为一个桶

    0 1 2 3 4 5 6 7 8 9
    1 108                
    3 149                
    5                  
    6                  
    7                  
    12                  
    25                  
    33                  
    36                  
    44                  
    53                  
    87                  
    89                  

    按百位位排序结果为:{1, 3, 5, 6, 7, 12, 25, 33, 36, 44, 53, 87, 89, 108, 149},百位排序完成这个排序操作已经完成了。

    五、代码实现

    public class JavaSort {
        public static void main(String[] args) {
            int a [] =new int []{6,5,7,3,1,12,33,53,25,89,108,149,44,87,36};
            System.out.println("排序前的数组:"+Arrays.toString(a));
            bucketSort(a);
            System.out.println("排序后的数组:"+Arrays.toString(a));
        }
        
            
        
            /**
             * 该排序一共需要排序最大元素位数次排序,假如数组元素的最大值为345,那么需要排序三轮,第一轮按照个位数进行排序
             * 第二轮按照十位位数进行排序,第三轮按照百位数进行排序。
             * @param ary 未排序数据
             */
            private static void bucketSort(int[] ary) {
                
                int aryLen=ary.length;
                int len=aryLen;
                if(aryLen<=10) {
                    len=10;
                }
                int bucket [][] =new int [10][len];//用于存放每次排序存放的结果。
                int bucketCap []=new int[len];//每个桶子存放的数据量。bucketCap[i]表示i个桶有多少个数据量,所以len必须大于等于10
                int loop=1;//排序的轮数,第一次按个位数上的数字排序,第二次按照十位数上的数字排序
                int maxLoop=getMaxLoop(ary);//排序需要的最大轮数,即是数组元素中最大元素是几位数。
                int k=0;//每轮排序好的数据存放的索引位置
                while(loop<=maxLoop) {
                    for (int i = 0; i < aryLen; i++) {//将数组元素存放在相应的桶里面
                        int position=(int) (ary[i]/(Math.pow(10, loop-1))%10);//取出要排的数据,第一轮取出个位数,第二轮取出十位数...,,也是数组元素存放在哪个桶子中,桶子的索引值。
                        bucket[position][bucketCap[position]]=ary[i];
                        bucketCap[position]++;
                    }
                    
                    for (int i = 0; i < 10; i++) {//遍历所有的桶子,取出桶子的值,存放在原数组完成一轮排序
                        if(bucketCap[i]>0) {
                            for (int j = 0; j < bucketCap[i]; j++) {
                                ary[k]=bucket[i][j];
                                k++;
                            }
                            bucketCap[i]=0;//将桶子清空
                        }
                    }
                    System.out.println("第"+loop+"轮排序结果为"+Arrays.toString(ary));
                    loop++;//轮数加+
                    k=0;
                }
            
        }
    
    
            /**
             * 获取数组元素最大值的位数。
             * @param ary
             * @return 最大数的位数
             */
    
            private static int getMaxLoop(int[] ary) {
                int max=ary[0];
                for (int i = 1; i < ary.length; i++) {
                    if(max<ary[i]) {
                        max=ary[i];
                    }
                }
                int temp=max;
                int n=1;
                while((temp=temp/10)>0) {
                    n=n+1;
                }
                        
                return n;
            }
    
    }

    六、运行结果已经效率分析

    效率分析:

    时间复杂度为:O(n),空间复杂度为:O(10*n)

  • 相关阅读:
    PHP引用传值
    PHP快速排序
    PHP冒泡排序法
    Jquery EasyUI datagrid后台数据表格生成及分页详解
    polymer 测试
    imooc movie
    test markdown
    MEAN 27
    MEAN 26
    nodejs 负载均衡
  • 原文地址:https://www.cnblogs.com/shareAndStudy/p/12499656.html
Copyright © 2011-2022 走看看