计数排序算法

原理

针对于范围小数量大的数组,直接遍历一次对所有数进行计数,然后自己根据计数结果写数组

代码实现

void sort(int* arr, int n, int min, int max)    //不稳定
{
    const int RAN = max - min + 1;
    int* arrRes = (int*)malloc(sizeof(int) * n);
    int* arrCount = (int*)malloc(sizeof(int) * RAN);    //计数数组
    for (int i = 0; i < RAN; i++)
    {
        arrCount[i] = 0;
    }
   
    for (int i = 0; i < n; i++)
    {
        arrCount[arr[i] - min]++;
    }

    for (int i = 0, j = 0; i < RAN; i++)    
    {
        while (arrCount[i] > 0)
        {
            arrRes[j] = i + min;
            j++;
            arrCount[i]--;
        }
    }

    memcpy(arr, arrRes, sizeof(int) * n);
    free(arrRes);
    free(arrCount);
}

优化思路

原来的方法是不稳定的,因为数组是我们自己写的,这次我们把计数数组优化成增量数组,记录每种数最后的排序,然后倒序遍历原数组找到所有位置

void sortP(int* arr, int n, int min, int max)   //稳定
{
    const int RAN = max - min + 1;
    int* arrRes = (int*)malloc(sizeof(int) * n);
    int* arrCount = (int*)malloc(sizeof(int) * RAN);    
    for (int i = 0; i < RAN; i++)
    {
        arrCount[i] = 0;
    }

    for (int i = 0; i < n; i++)
    {
        arrCount[arr[i] - min]++;
    }

    for (int i = 1; i < RAN; i++)   //修改成增量数组,记录每种数字最后一个的排序位置
    {
        arrCount[i] = arrCount[i - 1] + arrCount[i];
    }

    for (int i = n - 1; i >= 0; i--)    //倒序获取每个数字位置
    {
        arrRes[arrCount[arr[i] - min] - 1] = arr[i];
        arrCount[arr[i] - min]--;
    }

    memcpy(arr, arrRes, sizeof(int) * n);
    free(arrRes);
    free(arrCount);
}

评价

针对特定范围小数量大的数组十分好用

上一篇:Ran out of input


下一篇:编程入门笔记1