基本排序算法 之八 ——计数排序

 


基本排序算法总结与对比 之八  ——计数排序 


1、计数排序 

       前面介绍的七种排序算法都属于 基于比较的排序算法(CBA式算法)。这类算法的共同点就是:时间复杂度最优只能到O(nlogn)。接下来包括这次介绍的三种算法都属于非比较算法,其时间复杂度平均情况下均为O(k·n),k为常数。

       计数排序 又叫 鸽巢排序。就是用一个与 数列最大数数值 相等长度 的数组记录每个元素出现的次数。然后遍历记录数组,按照记录的个数打印下标。这种排序在数值小的时候特别快。

       但是,也特别不实用。一是 最大数太大就得开一个特大的数组;二是 数组下标只能为非负整数。

//找出数列最大数
int findMax(int arr[], int lo, int hi)
{
    int max = *(arr + lo);
    while(++lo < hi)
    {
        if (*(arr + lo) > max) max = *(arr + lo);
    }
    return max; 
}

void countSort(int arr[], int lo, int hi)
{
    int maxNum = findMax(arr, lo, hi);
    size_t *count = new size_t[maxNum + 1];    //建一个能装maxNum + 1个数的数组
    for(int j = 0; j < maxNum + 1; j++) count[j] = 0;    //置零
    
    for(int i = lo; i < hi; i++)
    {
        count[*(arr + i)]++;
    }
    
    int *p = arr;
    for(int j = 0; j < maxNum + 1; j++)
    {
        while(count[j]--)
        {
            *p++ = j;
        }
    }
}

       显然,该算法时间复杂度为O(2n),而且是稳定的。

       关于计数排序有个 特殊的 版本叫 位图排序。它只适用于无重复的非负整数数列。它的原理是开辟一段内存,用内存里的0,1表示 对应位数数值 的有无。这样可以大量节省内存空间,提高运算速度。 同样,他也特别不实用!位图排序相关内容将不再介绍。

你可能感兴趣的:(数据结构与算法基础)