若要排序的集合 \mathscr {S} 中, 最大的元素為 n, 最小的元素為 m, 那麼我們可以為 \mathscr {S} 配置至少 n - m + 1 個空間. 我們將這些額外配置的輔助空間稱為桶 (bucket). 若 e \in \mathscr {S}, 則必定有 e \in [m, n], 因此我們就把它放入第 e - m + 1 個空間中即可. 如果集合中的元素存在重複的話, 我們可以把上面的 n - m + 1 個空間更換成 n - m + 1 個前向連結串列 (《【資料結構】前向連結串列》).
#include <algorithm>
#include <forward_list>
int mapping(int x, int base) {
return base ? (base > 0 ? x - base : x + -base) : x;
}
typename std::forward_list<int>::const_iterator before_last(const std::forward_list<int> &list) {
auto begin {list.cbefore_begin()};
while(true) {
auto after_begin {begin};
++after_begin;
if(after_begin == list.cend()) {
return begin;
}
++begin;
}
}
void bucket_sort(int arr[], int size) {
const auto max {*std::max_element(arr, arr + size)};
const auto min {*std::min_element(arr, arr + size)};
const auto range {max - min + 1};
auto list_array {new std::forward_list<int>[range]};
for(auto i {0}; i < size; ++i) {
auto index {mapping(arr[i], min)};
list_array[index].insert_after(before_last(list_array[index]), arr[i]);
}
std::forward_list<int> r {};
for(auto i {0}; i < range; ++i) {
r.merge(list_array[i]);
}
delete[] list_array;
auto it {r.cbegin()};
for(auto i {0}; it not_eq r.cend(); ++i) {
arr[i] = *it++;
}
}