桶排序

當(dāng)待排序的隨機(jī)序列密集的分布于一個(gè)狹窄區(qū)間時(shí),使用計(jì)數(shù)排序速度比較快,當(dāng)待排序的隨機(jī)序列比較均勻的分布于一個(gè)較寬區(qū)間時(shí),可以考慮使用桶排序。桶排序的時(shí)間復(fù)雜度為O(n),空間復(fù)雜度也為O(n)

 既然一個(gè)待排序的隨機(jī)序列比較均勻的分布于一個(gè)區(qū)間,就很容易散列到各個(gè)桶中,假設(shè)有 n 個(gè)元素比較均勻的散列到 m 個(gè)桶中,則每個(gè)桶中的元素?cái)?shù)目約為 n/m,可以使用普通排序算法對(duì)每個(gè)桶中的元素排序,排序完畢后再把所有元素復(fù)制到最初序列的位置覆蓋原始序列。實(shí)際應(yīng)中n/m 通常很小,可以使用直接插入排序給每個(gè)桶中的元素排序,總的時(shí)間復(fù)雜度為O(n + m*(n/m)2 + n) = O(n2/m + 2n)  = O(n)。如果每個(gè)桶的元素用鏈表存儲(chǔ),鏈表可以用歸并排序,各桶排序完畢后把各個(gè)鏈表連接起來(lái)就可以了,省去一次復(fù)制元素的麻煩,這樣操作的時(shí)間復(fù)雜度為O(n + m(n/m)log(n/m)) = O(n + nlogk) = O(n)

以隨機(jī)整數(shù)為例,桶排序過(guò)程如下表。

48 40 66 91 47 68 31 30 29 23 99 35 23 88 88 87

待排序的隨機(jī)序列

01      2              3             4        5   6    7  8               9  

桶號(hào)

     29 23 23   31 30 35   48 40 47   66 68   88 88 87   91 99  

散列(/10)到各個(gè)桶內(nèi)

     23 23 29   30 31 35   40 47 48   66 68   87 88 88   91 99 

各桶分別排序

23 23 29 30 31 35 40 47 48 66 68 87 88 88 91 99        

最終排序結(jié)果


 1 inline unsigned long power2ceil(unsigned long x)
 2 {
 3   --x;
 4   x |= x >> 1;
 5   x |= x >> 2;
 6   x |= x >> 4;
 7   x |= x >> 8;
 8   x |= x >> 16;
 9 //  x |= x >> 32;
10   return ++x;
11 }
12 
13 inline unsigned long hash_bits(unsigned long x)
14 {
15  unsigned long sum = 0;
16  for(; x > 1; x >>= 1)
17    ++sum;
18  return sum;
19 }
20 
21 // non-portable implementation only for unsigned long type
22 template <typename Compare>
23 void bucket_sort(std::vector<unsigned long>& v, Compare cmp)
24 {
25  unsigned long max = *max_element(v.begin(), v.end());  // 見(jiàn)本主頁(yè)的計(jì)數(shù)排序
26  unsigned long min = *min_element(v.begin(), v.end());    // 見(jiàn)本主頁(yè)的計(jì)數(shù)排序
27  unsigned long max_bits = hash_bits(power2ceil(max - min));
28  unsigned long base = hash_bits(power2ceil(v.size()) / 100);
29  unsigned long bins = 1 << base;
30  unsigned long offset = (max_bits <= base ? base >> 7 : max_bits - base);
31  unsigned long pits = 128;
32  typedef std::vector<unsigned long> VECTOR;
33   std::vector<VECTOR> vec(bins + 1);
34  for(VECTOR::size_type i = 0; i < vec.size(); ++i)
35     vec[i].reserve(pits);
36  for(VECTOR::size_type i = 0; i < v.size(); ++i)
37     vec[(v[i] - min) >> offset].push_back(v[i]);
38  for(VECTOR::size_type i = 0; i < vec.size(); ++i)
39    insertion_sort(vec[i].begin(), vec[i].end(), cmp);           // 插入排序見(jiàn)本主頁(yè)的快排
40  unsigned long k = 0;
41  for(std::vector<VECTOR>::size_type i = 0; i < vec.size(); ++i)
42    for(VECTOR::size_type j = 0; j < vec[i].size(); ++j)
43      v[k++= vec[i][j];
44 }