基数排序

基数排序
基数排序是一种非比较型的排序,适用于整数排序。基本的原理是将数组从个位开始到最高为依次排序,数组达到排序状态。
以数组[21, 66, 867, 9, 13, 87, 56, 121]为例,首先按照个位排序,排序后数组为:
    [21, 121, 13, 66, 56, 867, 87, 9], 再按照十为排序,排序后数组变成:
    [9, 13, 21, 121, 56, 66, 867, 87], 在按照百位排序,排序后数组变成:
    [9, 13, 21, 56, 66, 87, 121, 867], 排序完成。

基数排序时间复杂度是o(k*n), 其中k为数组元素最大位数,n为数组元素个数。
空间复杂度为n,因为需要同样大小的数组作为临时缓存,如果不考虑内存分配的时间,100个小于10000的随机数,

基数排序的时间是是插入排序的一半左右。

template<class T>
static size_t MaxDigit(T *list, size_t size)
{
    T maxValue = list[0];
    for (size_t i = 1; i < size; ++i)
    {
        if (maxValue < list[i])
            maxValue = list[i];
    }

    size_t maxDigit = 0;
    while (maxValue > 0)
    {
        ++maxDigit;
        maxValue = T(maxValue / 10);
    }

    return maxDigit;
}

template<class T>
static void RadixSort(T *list, size_t size)
{
    //T *temp = new T[size]{ 0 };
    T temp[100] = { 0 };
    memcpy((void*)temp, (void*)list, size*sizeof(T));

    const size_t RADIX = 10;
    size_t counter[RADIX] = { 0 };

    size_t seed = 1;
    size_t maxDigit = MaxDigit(list, size);
    for (size_t i = 1; i <= maxDigit; ++i)
    {
        memset((void*)counter, 0, 10 * sizeof(T));

        for (size_t j = 0; j < size; ++j)
        {
            size_t n = size_t(list[j] / seed) % RADIX;
            ++counter[n];
        }

        for (size_t j = 1; j < RADIX; ++j)
        {
            counter[j] = counter[j - 1] + counter[j];
        }

        for (int j = size-1; j >= 0; --j)
        {
            size_t n = size_t(list[j] / seed) % RADIX;
            temp[counter[n] - 1] = list[j];
            --counter[n];
        }

        memcpy((void*)list, (void*)temp, size*sizeof(T));

        seed *= RADIX;
    }

    //delete [] temp;
    //temp = NULL;
}

static void RadixSortTest()
{
    const int size = SortDefaultSize;
    int list[size] = { 0 };
    FillRandomValue(list, size);
    PrintArray(list, size);

    Performance *pPerformance = new Performance("RadixSort: ");

    RadixSort(list, size);

    delete pPerformance;
    pPerformance = NULL;

    PrintArray(list, size);
}


维基百科-基数排序

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值