其大致思想是对值域进行分块,每块分别排序。由于每块元素不多,一般使用插入排序。如果使用稳定的内层排序,并且将元素插入桶中时不改变相对顺序,那么桶排序就是稳定的。
-如果待排序数据是随机生成的,将值域平均分成 $n$ 块的期望时间复杂度是 $O(n)$,证明可以参考算法导论或 [维基百科](https://en.wikipedia.org/wiki/Bucket_sort)。
+如果待排序数据是随机生成的,将值域平均分成 $n$ 块的期望时间复杂度是 $O(n)$ ,证明可以参考算法导论或 [维基百科](https://en.wikipedia.org/wiki/Bucket_sort) 。
C++ 代码:
}
}
-void bucket_sort()
-{
- int bucket_size = w / n + 1;
- for (int i = 0; i < n; ++i)
- {
- bucket[i].clear();
- }
- for (int i = 1; i <= n; ++i)
- {
- bucket[a[i] / bucket_size].push_back(a[i]);
- }
- int p = 0;
- for (int i = 0; i < n; ++i)
- {
- insertion_sort(bucket[i]);
- for (int j = 0; j < bucket[i].size(); ++j)
- {
- a[++p] = bucket[i][j];
- }
+void bucket_sort() {
+ int bucket_size = w / n + 1;
+ for (int i = 0; i < n; ++i) {
+ bucket[i].clear();
+ }
+ for (int i = 1; i <= n; ++i) {
+ bucket[a[i] / bucket_size].push_back(a[i]);
+ }
+ int p = 0;
+ for (int i = 0; i < n; ++i) {
+ insertion_sort(bucket[i]);
+ for (int j = 0; j < bucket[i].size(); ++j) {
+ a[++p] = bucket[i][j];
}
+ }
}
```
-
计数排序分为三个步骤:
-1. 计算每个数出现了几次。
-2. 求出每个数出现次数的前缀和。
-3. 利用出现次数的前缀和,从右至左计算每个数的排名。
+1. 计算每个数出现了几次。
+2. 求出每个数出现次数的前缀和。
+3. 利用出现次数的前缀和,从右至左计算每个数的排名。
伪代码:
+
$$
\begin{array}{ll}
1 & \textbf{Input. } \text{An array } A \text{ consisting of }n\text{ positive integers no greater than } w. \\
13 & \textbf{return } B
\end{array}
$$
+
C++ 代码:
```cpp
int n, w, a[N], cnt[W], b[N];
-void counting_sort()
-{
- memset(cnt, 0, sizeof(cnt));
- for (int i = 1; i <= n; ++i) ++cnt[a[i]];
- for (int i = 1; i <= w; ++i) cnt[i] += cnt[i - 1];
- for (int i = n; i >= 1; --i) b[cnt[a[i]]--] = a[i];
+void counting_sort() {
+ memset(cnt, 0, sizeof(cnt));
+ for (int i = 1; i <= n; ++i) ++cnt[a[i]];
+ for (int i = 1; i <= w; ++i) cnt[i] += cnt[i - 1];
+ for (int i = n; i >= 1; --i) b[cnt[a[i]]--] = a[i];
}
-```
\ No newline at end of file
+```