计数排序与基数排序

计数排序与计数排序的思想都来自于桶排序,桶排序的大体思想为:若N个关键字均可以映射到0-M的整数范围内,则可以建立M+1大小的桶,然后依次遍历N个关键字,依次将他们放到自己对应的那个桶里面,最后从0开始依次将桶中的元素倒出即可。

计数排序:

大体思想:假设序列值均为整数,首先获得序列的最大值valueMax和最小值valueMin,建立一个大小为(valueMax-valueMin+1)的数组count,遍历该序列data,count[data[i]-valueMin]++。如此,count中第k个位置上的元素即为k+valueMin出现的次数,再根据次数复制到data中去,完成排序。

代码如下:

    public static void countSort(int[] data) {
        // 找到最小值 最大值
        int valueMax=data[0],valueMin=data[0];
        for(int i=0;i<data.length;i++) {
            if(data[i]>valueMax) {
                valueMax=data[i];
            }
            if(data[i]<valueMin) {
                valueMin=data[i];
            }
        }
        int[] count=new int[valueMax-valueMin+1];
        for(int temp:data) {
            count[temp-valueMin]++;
        }
        //把值复制到data中
        for(int i=0,k=0;i<count.length;i++) {
            for(int j=0;j<count[i];j++) {
                data[k++]=i+valueMin;
            }
        }
    }

复杂度分析:

显然计数排序是N的线性范围复杂度的排序,其时间复杂度为O(N)。空间复杂度由于建了M个桶,因此其空间复杂度为O(M)。

此外计数排序是稳定的。

基数排序:

大体思想:一般用于多个关键字的排序(例如扑克牌中的花色和面值大小),基数排序分为两种主位优先和次位优先两种,下面主要介绍用的跟广泛的次位优先。所谓次位优先,先以次位关键字建立桶,将所有元素按照关键字依次扔进桶中,再依次从小到大从桶中放回到原数组。对于多个关键字依次从次到主重复上述操作即可完成排序。

本文以三位数的整数排序为例,将三位数的百位、十位、个位作为关键字,显然百位是主位。其代码如下:

    public static void radixSort(int[] data) {
        //以三位数的整数为例
        int N=10;
        //创建桶
        List<LinkedList<Integer>> buck=new ArrayList<LinkedList<Integer>>(N);
        for(int i=0;i<N;i++) {
            buck.add(new LinkedList<Integer>());
        }
        for(int i=0,k=1;i<3;i++,k*=10) {// 从低位数第i位 0=个位 1=百位
            int temp=0;
            for(int j=0;j<data.length;j++) {
                temp=data[j]%(10*k)/k;//取出i位上的数
                buck.get(temp).add(data[j]);
            }
            //往data中倒
            for(int j=0,m=0;j<N;j++) {
                while(buck.get(j).size()>0) {
                    data[m++]=buck.get(j).remove();
                }
            }
        }
    }

复杂度分析:

从上述代码中可以发现,花费时间为3*(N+10),其时间复杂度为O(D(N+M)),其中D为关键字的个数,M为桶的个数,N为序列长度。 

空间复杂度为O(N),本文中所用的list均需要存放所有元素。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值