1. 程式人生 > 其它 >計數排序演算法

計數排序演算法

原理

針對於範圍小數量大的陣列,直接遍歷一次對所有數進行計數,然後自己根據計數結果寫陣列

程式碼實現

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);
}

評價

針對特定範圍小數量大的陣列十分好用