重複造輪子系列--桶排序

來源:互聯網
上載者:User

標籤:總結   集中   main   while   代碼實現   資料結構   sse   元素   簡便   

理解了基數排序,也就理解了桶排序。

桶排序就是基數排序的一種最佳化,從MSD開始,即取最高位來排一次序,如果最高位沒有重複(意味著沒有衝突需要處理),是演算法的最佳狀態,O(n)。

如果有衝突,就將衝突的元素存放到對應的桶裡(代碼就是一個鏈表或者數組或者stl容器),然後對每個桶進行一次插入排序,平均情況的話衝突很小的,桶裡的元素的數量就不多,速度很快,

如果衝突集中在幾個桶甚至一個桶裡,那麼就出現了演算法的最差情形,也就是O(n^2)的複雜度。

 

下面是例子代碼實現:

 1 template<typename _InIt> 2 void bucket_sort(_InIt first, _InIt last, short decimal_bits) { 3     typedef typename iterator_traits<_InIt>::value_type _ValueType; 4     typedef typename vector<_ValueType>::iterator _Iterator; 5  6     int n = last - first; 7     if (n <= 0) return; 8  9     vector< vector<_ValueType> > v(n, vector<_ValueType>());10     _InIt it = first;11     for(; it!=last; ++it) {12         int i = bucket_index(*it, decimal_bits);13         v[i].insert(v[i].begin(), *it);14     }15 16     typename vector< vector<_ValueType> >::iterator ite = v.begin();17     less_equal<_ValueType> cmp;18     it = first;19 20     for(; ite!=v.end(); ++ite) {21         if (ite->empty()) continue;22         insert_sort(ite->begin(), ite->end(), cmp);23         for(_Iterator _it=ite->begin(); _it!=ite->end(); ++_it)24             *it++ = *_it;25     }26 }

上面預設採用了遞增排序,如果要遞減,就反向迭代並使用greater_equal。

為圖簡便,這裡把元素直接放到輸入的容器了。

整個測試程式:

 1 #include <iostream> 2 #include <vector> 3 #include <cassert> 4  5 using namespace std; 6  7 template<typename _InIt, typename _Func> 8 void __insert_sort(_InIt first, _InIt last, _Func& Func) { 9     typedef typename iterator_traits<_InIt>::value_type _ValueType;10 11     for (_InIt it = first+1; it != last+1; ++it) {12         _ValueType key = *it;13         _InIt ite = it - 1;14         for (; (ite - first)>=0 && !Func(*ite, key); --ite)15             *(ite + 1) = *ite;16         *(ite + 1) = key;17     }18 }19 20 template<typename _InIt, typename _Func>21 void insert_sort(_InIt first, _InIt last, _Func& Func) {22     __insert_sort(first, last-1, Func);23 }24 25 int bucket_index(int num, int p) {26     assert(num >0 && p > 0);27     int s = 1;28     while (p-->0) s *= 10;29     return ((num%s)*10)/s;30 }31 32 template<typename _InIt>33 void bucket_sort(_InIt first, _InIt last, short decimal_bits) {34     typedef typename iterator_traits<_InIt>::value_type _ValueType;35     typedef typename vector<_ValueType>::iterator _Iterator;36 37     int n = last - first;38     if (n <= 0) return;39 40     vector< vector<_ValueType> > v(n, vector<_ValueType>());41     _InIt it = first;42     for(; it!=last; ++it) {43         int i = bucket_index(*it, decimal_bits);44         v[i].insert(v[i].begin(), *it);45     }46 47     typename vector< vector<_ValueType> >::iterator ite = v.begin();48     less_equal<_ValueType> cmp;49     it = first;50 51     for(; ite!=v.end(); ++ite) {52         if (ite->empty()) continue;53         insert_sort(ite->begin(), ite->end(), cmp);54         for(_Iterator _it=ite->begin(); _it!=ite->end(); ++_it)55             *it++ = *_it;56     }57 }58 59 template<typename T>60 void print(const vector<T>& v) {61     for(vector<int>::const_iterator it=v.begin(); it != v.end(); it++)62            cout << *it << " ";63         cout << endl;64 }65 66 int main() {67     int lst[] = {78,17,39,26,72,94,21,12,23,68};68     vector<int> v(lst, lst+10);69 70     bucket_sort(v.begin(), v.end(), 2);71     print(v);72 73     return 0;74 }

 

寫完這些例子,在準備刷難度高一點的演算法之前,小小的總結了一下。

這些例子的適用範圍都很小,僅供學習使用,比如上面的插入排序,迭代器僅僅對vector有效,如果有自己的資料結構容器,最好是為它實現一個隨機訪問迭代器。

 

重複造輪子系列--桶排序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.