算法导论之计数排序

1.计数排序是一种非常快捷的稳定性强的排序方法,时间复杂度O(n+k),其中n为要排序的数的个数,k为要排序的数的组大值。计数排序对一定量的整数排序时候的速度非常快,一般快于其他排序算法。但计数排序局限性比较大,只限于对整数进行排序。计数排序是消耗空间复杂度来获取快捷的排序方法,其空复杂度为O(K)同理K为要排序的最大值。

2.计数排序的基本思想为一组数在排序之前先统计这组数中其他数小于这个数的个数,则可以确定这个数的位置。例如要排序的数为 7 4 2 1 5 3 1 5;则比7小的有7个数,所有7应该在排序好的数列的第八位,同理3在第四位,对于重复的数字,两个1分别排在第1位和第2位(暂且认为第一个1比第二个1小),两个5同理排在第6位和第7位。

3.计数排序的实现办法

  首先需要三个数组,第一个数组input Arr,第二个数组记录比某个数小的数字的个数所以第二个数组的大小应当为K(数列中最大数的大小),第三个数组output Arr。

  接着需要确定数组最大值并确定B数组的大小。并对每个数由小到大的记录数列中每个数的出现次数。因为是有小到大通过出现次数可以通过前面的所有数的出现次数来确定比这个数小的数的个数,从而确定其位置。

  对于重复的数,每排好一个数则对其位置数进行减减操作,以此对完成其余相同的数字进行排位。

计数排序的要求是每个输入的元素必须是小于k的整数。

//A是input,B是output,C的length是k
//这里找出最大的是k,但是数组C【k】越界,所以这里我们在排序的时候让K+1,刚好就C【0】到C【k】了
//C中记录的是比某个元素小的数字的个数,C中的坐标就是A中元素的值
//这里所以待排序的数字必须比k小
//C[A[j]]表示小于等于A[j]的元素的个数,也就是排完序之后的该元素的位置
public class CountSort {

    int toFindk(int A[]){//找出A【】中最大元素k
        int max=A[0];
        for(int i=1;i<A.length;i++){
            if(A[i]>max){
                max=A[i];
            }
        }
        return max;
    }


    void countingSort(int A[],int B[],int k){//这里的k是以前的K+1因为countSort.countingsort(A, B, k+1);
        int C[]=new int[k];
        for(int i=0;i<k;i++){
            C[i]=0;
        }

        for(int j=0;j<A.length;j++){
            C[A[j]]=C[A[j]]+1;//把A中的数值转化为C中对应位置的个数,C就是统计A中相等的元素存储在c中
        }

        for(int j=1;j<k;j++){
            C[j]=C[j]+C[j-1];//小于等于j的元素的个数
        }

        for(int j=A.length-1;j>=0;j--){
            B[C[A[j]]-1]=A[j];//注意这里要减1,C[A[j]]表示小于等于A[j]的元素的个数,也就是排完序之后的当前元素A[j]的位置
            C[A[j]]=C[A[j]]-1;
        }
    }

    public static void main(String[] args){
        int A[]={2,5, 3,0,2,3,0,3};
        int B[]=new int[A.length] ;
        int k;
        CountSort countSort=new CountSort();
        k=countSort.toFindk(A);
        countSort.countingSort(A, B, k+1);
        for(int i=0;i<B.length;i++){
            System.out.print(B[i]+"   ");
        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值