1. 程式人生 > 其它 >資料結構與演算法 - 基數排序

資料結構與演算法 - 基數排序

基數排序

基數排序是一種非比較型整數排序演算法,其原理是將資料按位數切割成不同的數字,然後按每個位數分別比較。

假設說,我們要對 100 萬個手機號碼進行排序,應該選擇什麼排序演算法呢?排的快的有歸併、快排時間複雜度是 \(O(n \log n)\),計數排序和桶排序雖然更快一些,但是手機號碼位數是11位,那得需要多少桶?記憶體條表示不服。

這個時候,我們使用基數排序是最好的選擇。

我們以[ 892, 846, 821, 199, 810,700 ]這組數字來做例子演示。

首先,建立十個桶,用來輔助排序。

先排個位數,根據個位數的值將資料放到對應下標值的桶中。

排完後,我們將桶中的資料依次取出。

那麼接下來,我們排十位數。

最後,排百位數。

排序完成。

程式碼實現

基數排序可以看成桶排序的擴充套件,也是用桶來輔助排序,程式碼如下:

void sort(vector<int> arr)
{
    int length = arr.size();

    int max = arr[0];
    for(int i = 0; i < length; i++) {
        if(arr[i] > max) {
            max = arr[i];
        }
    }

    // 當前排序位置
    int location = 1;

    // 桶列表
    vector<vector<int>> bucketList(10);

    while(true) {
        // 判斷是否排完
        int dd = (int)pow(10, location-1);
        if(max < dd) {
            break;
        }

        // 資料入桶
        for(int i = 0; i < length; i++) {
            int number = (arr[i]/dd) % 10;
            bucketList[i].push_back(arr[i]);
        }

        // 寫回陣列
        int nn = 0;
        for(int i=0; i < 10; i++) {
            int size = bucketList[i].size();
            for(int ii=0; ii < size; ii++) {
                arr[nn++] = bucketList[i][ii];
            }
            bucketList[i].clear();
        }
        location++;
    }
}

其實它的思想很簡單,不管你的數字有多大,按照一位一位的排,0 - 9 最多也就十個桶:先按權重小的位置排序,然後按權重大的位置排序。

當然,如果你有需求,也可以選擇從高位往低位排。