排序算法-计数排序(CountingSort)-C

思路:

计数排序不是基于比较的排序,其核心思想是将输入数据的值转换为键值作为新开辟数组的下标,使用该下标对应数组元素的大小代表该值在数组中出现的次数。(一般建议数组元素为正整数,不过对于负整数和浮点数,也可以通过额为的修正来进行排序)。

基本步骤:

  1. 计算数组中的最大元素和最小元素;
  2. 根据数组中元素值的大小范围建立一个计数数组;
  3. 计算原始数组中每个值出现的次数,并插入到计数数组中;
  4. 依次将计数数组中不为空的元素的下标对应的值输出到原始数组中。

时间复杂度:

最好:O(n+k);平均:O(n+k);最坏:O(n+k) (n为元素个数,k为计数数组的大小)

程序:

void find_min_max(int array[],int array_size,int *min,int *max)
{
    int min_p,max_p,i;
    min_p=0;
    max_p=array_size-1;
    for(i=0;i<array_size;i++)
    {   
        if(array[i]<array[min_p])   
            min_p=i;
        if(array[i]>array[max_p])
            max_p=i;
    }   
    *min=array[min_p];
    *max=array[max_p];
}

void counting_sort(int array[],int array_size)
{
    int i,j,min,max,size,offset;
    find_min_max(array,array_size,&min,&max);
    offset=0-min;
    size=max-min+1;
    int * count_array=calloc(size,sizeof(int));
    if(count_array==NULL)
    {   
        printf("No full space! \n");
        return;
    }   
    for(i=0;i<array_size;i++)
    {   
        count_array[array[i]+offset]++;
    }   
    for(i=0,j=0;i<size;i++)
    {   
        while(count_array[i]--)
        {   
            array[j++]=i-offset;
        }   
    }   
    free(count_array);
}
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;  
    int array[]={100,96,88,75,63,52,41,36,28,96,19,6,0,-19,-105,28,52,52,52};
    int array_size=sizeof(array)/sizeof(int);
    printf("Original array:\n");
    for(i=0;i<array_size;i++)
        printf(" %d, ",array[i]);
    printf("\n");
    counting_sort(array,array_size);
    printf("Sorted array:\n");
    for(i=0;i<array_size;i++)
        printf(" %d, ",array[i]);
    printf("\n");
    return 0;
}  

参考:

https://www.cnblogs.com/onepixel/articles/7674659.html

https://www.runoob.com/w3cnote/ten-sorting-algorithm.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值