基数排序

基数排序

介绍

基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。

实现思想

将所有待比较数值统一为同样的位数长度,位数较短的前面补零,然后从最低位开始,依次进行一次排序,这样从最低为排序,一直到最高位排序完成之后,数列就变成了一个有序序列

特点

  1. 它是桶排序的扩展,速度很快
  2. 基数排序是稳定性的排序,基数排序是效率高的稳定性的算法
  3. 基数排序是空间换时间的经典算法,占内存很大,当对海量数据排序时,将造成 OutOfMemoryError

代码实现

//基数排序
public static int[] radixSort(int[] arr){
    //设置一个二维数组充当桶,行表示第几个桶(共10个桶 0~9),列表示桶的容量
    int[][] bucket=new int[10][arr.length];
    //定义一个一维数组记录每个桶的存放数据
    int[] nums=new int[10];
    int searchMax=seachMax(arr);//寻找出数组中最大元素的位数
    int p=0;
    while(p<=searchMax){
        for(int i=0;i<arr.length;i++){
            int num=(int)(arr[i]/(Math.pow(10,p))%10);
            bucket[num][nums[num]]=arr[i];
            nums[num]++;
        }
        p++;
        int index=0;
        for(int i=0;i< 10;i++){
            if(nums[i]!=0){
                for(int j=0;j<nums[i];j++){
                    arr[index++]=bucket[i][j];
                }
            }
            nums[i]=0;//统计完个位数并排序后将此数组的值清零,为其统计十位数做准备
        }

    }
    return arr;
}

//查找数组中最大元素的位数
private static int seachMax(int[] arr){
    int max=arr[0];
    for(int num:arr){
        if(max<num){
            max=num;
        }
    }
    return max+"".length();//让max+""后转化为字符串型,再求出其长度,则为整型数的长度
}
//存在负数的解决方法,找出最小值,若最小值为负数,则让数组中所有的数加上最小的负数,之后再减去此数

稳定性与复杂性

稳定性:若数组中出现重复元素,若排序后重复元素还按照源数组中的先后顺序排列,则称之为稳定,否则为不稳定

in-place:不占用额外内存

out-place:占用额外内存

n:数据规模

d 为位数,r 为基数,n 为原数组个数

排序算法 平均时间复杂度 最好情况 最坏情况 空间复杂度 排序方式 稳定性
基数排序 O(d*(n+r)) O(d*(n+r)) O(d*(n+r)) O(n+r) out-place 稳定

posted on 2021-04-30 21:20  凡人精灵  阅读(96)  评论(0)    收藏  举报

导航