美文网首页
算法:排序(三)

算法:排序(三)

作者: 熊白白 | 来源:发表于2017-07-03 21:14 被阅读21次

    计数排序与基数排序

    利用桶排序的思想可以达到O(N)的时间复杂度,但仅限于特定的情况。

    计数排序

    已知数据取值在狭小且有限的集合内,则可以使用计数排序。思路是预先准备好表征元素取值的计数桶,遍历元素时,使得表征该元素取值的桶计数值加一。遍历完成后倒出元素即可。

    int* countingSort(int* A, int n) {
        //获取最大最小值以便分配桶
        int min=A[0],max=A[0];
        for(int i=1;i<n;++i){
            if(A[i]>max)
                max=A[i];
            if(A[i]<min)
                min=A[i];
        }
        //分配桶:一个计数数组
        int* ss=new int[max-min+1]();
        //对每个元素找到其对应的桶
        for(int i=0;i<n;++i)
            ss[A[i]-min]++;
        //遍历所有的桶,把元素倒回去
        int pos=0;
        for(int i=0;i<max-min+1;++i){
            while(ss[i]--){
                A[pos++]=i+min;
            }
        }
        delete[] ss;
        return A;
    }
    

    基数排序

    基数排序可以看做是计数排序的扩展。适用于元素有多个键值,键值取值狭小且有限的情况。思路是按照键值优先级从低到高进行排序。
    举例:正整数的个位/十位/百位数字就是表征数字大小的各个键值,先按照个位数字放入各个桶内,然后倒出;再按照十位/百位数字继续此操作。

    CODE

    int* radixSort(int* A, int n) {
        const int M=10;
        //临时存储数据
        int* s=new int[n];
        //计数:每个键值各对应多少元素
        int* c=new int[M]();
        //被除数,用以计算当前位置的数字
        int x=1;
        int number;
        for(int t=0;t<5;++t){  //假设元素不超过五位数
            //清零计数数组
            for(int m=0;m<M;++m)
                c[m]=0;
            //统计数组中各个number的数目
            for(int i=0;i<n;++i){
                number=A[i]/x%10;
                c[number]++;
            }
            //c数组做累加操作
            for(int m=1;m<M;++m)
                c[m]=c[m-1]+c[m];
            //经过累加后,c[m]表示第m号桶的终止位置后一位
            //正是因此,我们放桶的时候从后往前放.
            for(int i=n-1;i>=0;--i){
                number=A[i]/x%10;
                s[--c[number]]=A[i];
            }
            //从桶中倒回数组
            for(int i=0;i<n;++i){
                A[i]=s[i];
            }
            x*=10;
        }
        delete[] s;
        delete[] c;
        return A;
    }
    

    注意

    • 以上代码为了节省空间,所有的桶都位于数组s上的某一段,通过计数产生c数组,然后累加得到每个桶的尾后指针位置,以此访问桶。


    • 元素入桶时根据尾后指针进行遍历,所以需要从后向前遍历数组。
    • 如果不考虑空间花费,可以通过指针数组来创建类似于二维数组的结构来构造M个桶;或者使用队列等数据结构来处理。

    相关文章

      网友评论

          本文标题:算法:排序(三)

          本文链接:https://www.haomeiwen.com/subject/noxacxtx.html