计数排序——CountingSort

来源:互联网 发布:物业收费软件 编辑:程序博客网 时间:2024/06/05 16:12

计数排序

计数排序是线性排序的一种。能够在线性时间内完成给定序列的排序,但计数排序应用的场景就更加具体了。

基本思想:对每一个输入的元素x,确定小于x的元素个数。这样就可以直接把x放到它在输出数组中的位置了。例如,有17个元素小于x,则x应在第18个输出位置上,但当有几个相同元素时,就要略加修改。

下面是算法导论中给出的伪代码:

COUNTING_SORT(A, B, k)    let C[0...k] be a new array    for i = 0 to k        C[i] = 0    for j = 1 to A.length        C[A[j]] = C[A[j]] + 1    for i = 1 to k        C[i] = C[i] + C[i - 1]    for j = A.length downto 1        B[C[A[j]]] = A[j]        C[A[j]] = C[A[j]] - 1

有了伪代码,就很容易转换成代码

void Counting_Sort(int A[], int size){    int *B = NULL;    B = (int *) malloc(sizeof(int) * size);    for(int i = 0; i < size; i++)//临时数组的初始化        B[i] = 0;    for(int i = 0; i < size; i++)//记录元素的个数        B[A[i]]++;    for(int i = 0; i < size; i++)确定小于B[i]的元素个数        B[i] += B[i - 1];    int *C = NULL;    //C数组用来临时存放有序序列    C = (int *)malloc(sizeof(int) * size);    for(int i = 0; i < size; i++)    {        C[B[A[i]]] = A[i];        B[A[i]]--;    }    for(int j = 0; j < size; j++)//将有序序列赋值给数组A        A[i] = C[j];    free(B);   /*最后释放B和C的空间*/    free(C);}

其实,还可以使代码更简洁,省去临时数组A,像下面这样:

void Counting_Sort(int A[], int size){    int *B = NULL;    B = (int *) malloc(sizeof(int) * size);    for(int i = 0; i < size; i++)//临时数组的初始化        B[i] = 0;    for(int i = 0; i < size; i++)//记录元素的个数        B[A[i]]++;    int index = 0;    for(int i = 0; i < size; i++)//B中的下表就是原数中的元素    {                           //而B[i]的值代表元素的个数          while(B[i]-- > 0)        {            A[index++] = i;        }    }    free(B); }
0 0