数据结构基础(15) --基数排序
? ? 基數排序是一種借助“多關鍵字排序”的思想來實現“單關鍵字排序”的內部排序算法。
實現多關鍵字排序通常有兩種作法:
? ?最低位優先法(LSD)
? ? 先對K[0]{基數的最低位}進行排序,并按?K(0)?的不同值將記錄序列分成若干子序列之后,分別對?K[1]?進行排序,...,?K[d-1]依次類推,直至最后對最次位關鍵字排序完成為止。
? 最高位優先法(MSD)
? ? 先對?K[d-1]{基數的最高位}進行排序,然后對?K[d-2]進行排序,依次類推,直至對最主位關鍵字?K[0]?排序完成為止。
?
百度百科對基數排序做了如下介紹:
? ? 基數排序(radix?sort)是屬于“分配式排序”(distribution?sort),基數排序法又稱“桶子法”(bucket?sort),顧名思義,它是透過鍵值的部份資訊,將要排序的元素分配至某些“桶”中,藉以達到排序的作用,基數排序法是屬于穩定性的排序,在某些時候,基數排序法的效率高于其它的穩定性排序法。
?
鏈式基數排序基本步驟如下
? ? 1.將待排序記錄以數組存儲[或者以指針相鏈,構成一個鏈表]
? ? 2.”分配”時,按當前”關鍵字位”所取值,將記錄分配到不同的”鏈表/鏈隊列”(即不同的桶或堆中)中,每條鏈表中記錄的”關鍵字位”相同;
? ? 3.”收集”時,按當前關鍵字位取值從小到大(即將這n條鏈表(n的大小為基數的大小)按照編號,?依次將其中所有的元素取出)將各鏈表中的元素取出放入到原先的數組或鏈表中;
? ? 4.對每個關鍵字位均重復?2)?和?3)?兩步n次。
?
如采用LSD對{179,?208,?306,?93,?859,?984,?55,?9,?271,?33}(構成一個鏈表或者是數組)進行基數排序:
[第一步:按個位排]
?
[第二步:按十位排]
[第三步:按百位排]
?
代碼實現(以LSD為例):
//尋找數組中最大數字的位數 template <typename Type> unsigned int maxBits(Type *begin, Type *end) {unsigned int bits = 1;//standard作為基準, 如果array中的元素//大于standard, 則bits+1int standard = 10;for (Type *current = begin; current != end; ++current){while (*current >= standard){standard *= 10;++ bits;}}return bits; } /**說明:begin:數組起始end:數組結尾radix:基數*/ #define DEBUG template <typename Type> void radixSort(Type *begin, Type *end, int radix) {//找到數組中最大數字的位數int bits = maxBits(begin, end);//基數為radix, 則需要radix個鏈表std::list<Type> lists[radix];// 需要循環bits次for (int d = 0, factor = 1; d < bits; ++d, factor*=10){//分配...for (Type *current = begin; current != end; ++current){//取出相應位置上的數 (比如個位是1)int number = ((*current)/factor)%10;//則需要將之放到(分配到)標號為1的鏈表中lists[number].push_back(*current);}//收集...Type *current = begin;//對radix個鏈表中的元素進行收集for (int i = 0; i < radix; ++i){while (!lists[i].empty()){*current = lists[i].front();++ current;lists[i].pop_front();}} #ifdef DEBUG//打印排序的中間結果for (current = begin; current != end; ++ current){cout << *current << ' ';}cout << endl; #endif // DEBUG} }template <typename Type> void radixSort(Type *array, int arraySize, int radix) {return radixSort(array, array+arraySize, radix); }
時間復雜度分析:
? ? 設待排序列為n個記錄,d個關鍵碼,關鍵碼的取值范圍為radix,則進行鏈式基數排序的時間復雜度為O(d(n+radix)),其中,一趟分配時間復雜度為O(n),一趟收集時間復雜度為O(radix),共進行d趟分配和收集.
附-測試代碼:
int main() {int array[10];for (int i = 0; i < 10; ++i){array[i] = rand()%1000;}for (int i = 0; i < 10; ++i){cout << array[i] << ' ';}cout << endl;radixSort(array, 10, 10);for (int i = 0; i < 10; ++i){cout << array[i] << ' ';}cout << endl;return 0; }總結
以上是生活随笔為你收集整理的数据结构基础(15) --基数排序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何汉化美化Citrix的WEB界面
- 下一篇: WIN7 IE8的桌面图标解决了(简单有