標籤:總結 集中 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有效,如果有自己的資料結構容器,最好是為它實現一個隨機訪問迭代器。
重複造輪子系列--桶排序