码迷,mamicode.com
首页 > 编程语言 > 详细

[算法]计数排序

时间:2016-08-07 18:45:02      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:

  计数排序的思想在于统计比某个数小或等于它的个数。关键就在于统计,就随便举一个例子

有一个要从小到大排序的数组A[] = {3,4,1,5, 6}

如何确定比A[0]小的个数

定一个数组counter,counter用来统计,方法是这样的↓

将每个元素对应counter的下标,counter这个位加一,counter[A[i]]++

这样操作完了,counter数组变成了这样

pos  0  1  2  3  4  5  6  7  8

val  0  1  0  1  1  1  1  0  0

好像并不能直观地通过值来看出A[0]小的个数

但是如果想前缀和一样,从前往后加会发生什么情况?

pos  0  1  2  3  4  5  6  7  8

val  0  1  1  2  3  4  5  5  5

小于等于x的数(包括自己)就是counter[x]个

稍微想一下就能理解

按照这个数组把原数组中的元素拷贝到另一个数组里就行了

  按照这样做应该只能得个十二十分吧,因为貌似这样做对像下面这组数据不是

特别地灵

1 3 3 4 5

  另一个数组中的值应该是这样的

1 0 3 4 5

  这说明上面并不是完整的计数排序,还差在哪呢?拷贝的时候把counter对应位上

减一就行了(下次拷贝这个数就放在刚刚这个数的位置的前一个)


Code

#include<iostream>
#include<cstring>
using namespace std;
int* sorted;
int* counter;
void CountingSort(int *array, int len){
    sorted = new int[(const int)(len)];
    int maxv = array[0]; 
    int minv = array[0];
    for(int i = 1;i < len;i++){        //找出最大值和最小值,当然可以不这么做 
        maxv = max(array[i], maxv);    //counter数组定一个足够大的大小就行了 
        minv = min(array[i], minv);
    }
    counter = new int[(const int)(maxv + 1)];    //如果想省点内存还可以写成(maxv - minv + 2),下面改一下就行了 
    memset(counter, 0, sizeof(int) * (maxv + 1));
    for(int i = 0;i < len;i++){
        counter[array[i]]++;            //计数 
    }
    for(int i = minv;i <= maxv;i++){
        counter[i] += counter[i - 1];    //累加得到小于等于i的个数 
    }
    for(int i = len - 1;i >= 0;i--){    //拷贝,这里也可以从1循环到len - 1 
        sorted[--counter[array[i]]] = array[i]; 
    }
}
int n;
int *list;
int main(){
    cin>>n;
    list = new int[(const int)(n + 1)];
    for(int i = 0;i < n;i++)
        cin>>list[i];
    CountingSort(list, n);
    for(int i = 0;i < n;i++)
        cout<<sorted[i]<<" ";
    return 0;
}

 

[算法]计数排序

标签:

原文地址:http://www.cnblogs.com/yyf0309/p/5746773.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!