打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
浅谈排序算法实现 (计数排序、基数排序)

浅谈排序算法实现 (计数排序、基数排序)

  1、   计数排序

      计数排序是一种高效的线性排序,它通过计算一个集合中元素楚翔的次数来确定集合如何排列,计数排序不需要进行数据的比较,所有他的运行效率前面介绍的都高。

      计数排序(Counting sort)是一种稳定的排序算法。计数排序使用一个额外的数组Count_arr,其中第i个元素是待排序数组Arr中值等于i的元素的个数。然后根据数组Count_arr来将Arr中的元素排到正确的位置。

    分为四个步骤:

1.找出待排序的数组中最大和最小的元素

2.统计数组中每个值为i的元素出现的次数,存入数组Count_arr的第i项

3.对所有的计数累加(从Count_arr中的第一个元素开始,每一项和前一项相加)

4.反向遍历原数组:将每个元素i放在新数组的第Count_arr(i)项,每放一个元素就将Count_arr(i)减去1



上面的图不知道大家能看明白不,不过看代码也一样很容易就明白的!(代码已经测试过OK,有问题请留言)

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/**************************************************************
 *计数排序。
 *参数: data : 要排序的数组
 *       size :数组元素的个数
 *       k    :数组中元素数组最大值 +1 (这个需要+1)
 *返回值: 成功0;失败-1.      
 * ************************************************************/
int ctsort(int *data, int size, int k)
{
    int * counts = NULL,/*计数数组*/
        * temp = NULL;/*保存排序后的数组*/
    int i = 0;
    /*申请数组空间*/
    if ((counts = (int *) malloc( k * sizeof(int))) == NULL)
        return -1;
    if ((temp = (int *) malloc( k * sizeof(int))) == NULL)
        return -1;
    /*初始化计数数组*/
    for (i = 0; i < k; i ++)
        counts[i] = 0;
    /*数组中出现的元素,及出现次数记录*/
    for(i = 0; i < size; i++)
        counts[data[i]] += 1;
    /*调整元素计数中,加上前一个数*/
    for (i = 1; i < k; i++)
        counts[i] += counts[i - 1];
    /*使用计数数组中的记录数值,来进行排序,排序后保存的temp*/
    for (i = size -1; i >= 0; i --){
        temp[counts[data[i]] - 1] = data[i];
        counts[data[i]] -= 1;
    }
   
    memcpy(data,temp,size * sizeof(int));
    free(counts);
    free(temp);
    return 0;
}
int main()
{
    int a[8] = {1,0,2,1,4,5,7,4};
    int max = a[0],
        i = 0;
    /*获得数组中中的数值*/
    for ( i = 1; i < 8; i++){
        if (a[i] > max)
            max = a[i];
    }
    ctsort(a,8,max+1);
    for (i = 0;i < 8;i ++)
        printf("%d\n",a[i]);
}

基数排序

     基数排序是另外一种高效的线性排序算法。其方法为将数据按位分开,并从数据的最低有效位到最高的有效位进行比较依次排序,从而得到有序的集合。我们来看一个简单的例子:{15,12,49,16,36,40};

在对个位进行排序之后,其结果是{40,12,15,16,36,49};

在对十位进行排序后,其结果是{12,15,16,36,40,49};

 有一点很重要就是必须保证在对每个位进行排序时,其排序过程必须是稳定的。也就是说,数据在进行较低位排序之后,此数据的位置不应该改变,除非进行较高位比较时需要对它进行调整。也就是例子中,个为排序后是 12 15 16 在进行十位排序时,十位都是1,这时,不应该对其进行调整。下面直接看代码吧,代码中对个位进行排序时,采用的上面的计数排序的算法,保证了排序过程的稳定性。

/*rxsort.c*/
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/***************************************************************
 *用基数排序对十进制数进行排序
 *参数: data:数组元素  size:数组中元素的个数
 *       p:元素中最大的位数; k :基数 (十,八,二,16,进制等等)
 *返回值 :成功0,失败-1;
 * 函数有运行结束后,已排序好的序列保存在data中
 **************************************************************/
int rxsort(int *data, int size, int p, int k)
{
    int * counts,/*计数数组*/
        * temp;/*临时保存排序后的数组*/
    int index,
        pval,
        i,
        j,
        n;
    /*申请空间*/
    if ((counts = (int *)malloc(k * sizeof(int))) == NULL)
        return -1;
    if ((temp = (int *)malloc(size * sizeof(int))) == NULL)
        return -1;
    /*从低位到高位分别进行排序*/
    for (n = 0; n < p; n++){
        /*计数数组初始化*/
        for ( i = 0; i < k; i ++)
            counts[i] = 0;
        /*计算当前位的基数*/
        pval = (int) pow((double )k, (double)n);
       
        /*下面的实现参数计数排序部分*/
        for (j = 0; j < size; j ++){
            index = (data[j]/pval)%pval;
            counts[index] += 1;
        }
        for (i = 1; i < k; i ++)
            counts[i] += counts[i - 1];
        for(j = size - 1; j >= 0; j --){
            index = (data[j]/pval)%pval;
            temp[counts[index] - 1] = data[j];
            counts[index] -= 1;
        }
        memcpy(data, temp, size *sizeof(int));
    }
    free(counts);
    free(temp);
    return 0;
}

int main()
{
    int a[20] = {20,300,40,5,80,12,500,43,23,56,121,33,444,555,666,112,456,234,123,124};
    int i = 0;
    rxsort(a,20,3,10);
    for (i = 0; i< 20; i++)
        printf ("a[%d] = %d\n",i,a[i]);
}

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
学c++第7天--冒泡排序(数组元素排序)
Java程序员必学的8大排序算法之冒泡排序
Java学习路线:5分钟了解计数排序
02、一维数组练习例子
C语言‖冒泡排序算法
希尔排序算法的C语言实现示例
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服