資料結構與演算法 - 基數排序
阿新 • • 發佈:2022-03-01
基數排序
基數排序是一種非比較型整數排序演算法,其原理是將資料按位數切割成不同的數字,然後按每個位數分別比較。
假設說,我們要對 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 最多也就十個桶:先按權重小的位置排序,然後按權重大的位置排序。
當然,如果你有需求,也可以選擇從高位往低位排。