5-1 其他排序:桶排序
桶排序
桶排序是一种排序技术,它将元素分成若干组(或称桶)。这些桶是通过均匀分布元素而形成的。元素被划分到不同的桶中后,就可以使用任何其他排序算法对它们进行排序。最后,将排序后的元素按顺序重新组合在一起。
- 当输入数组元素均匀分布在一个范围内时,该方法效果很好。
- 这是一个稳定的算法,因为我们使用插入排序(它本身就是稳定的)来对各个桶进行排序。
桶排序算法:
创建n 个空桶(或列表),并对数组中的每个元素 arr[i] 执行以下操作。
- 将 arr[i] 插入 bucket[n*array[i]]
- 使用插入排序对各个桶进行排序。
- 将所有已排序的桶连接起来。
逐步图解
要对输入数组[0.78, 0.17, 0.39, 0.26, 0.72, 0.94, 0.21, 0.12, 0.23, 0.68]应用桶排序,我们遵循以下步骤:
步骤 1:创建一个大小为 10 的数组,其中每个槽位代表一个桶。

步骤 2:根据元素的范围,将输入数组中的元素插入到桶中。
将元素插入桶中:
- 将每个元素乘以桶数组的大小(本例中为 10)。例如,对于元素 0.23,我们得到 0.23 * 10 = 2.3。
- 将结果转换为整数,即可得到桶索引。在本例中,2.3 被转换为整数 2。
- 将元素插入到与计算出的索引对应的桶中。
- 对输入数组中的所有元素重复这些步骤。

步骤 3:对每个桶中的元素进行分类。
对每个桶中的元素进行排序:
- 应用稳定的排序算法(例如插入排序)对每个桶中的元素进行排序。
- 每个桶中的元素现在都已排序。

步骤 4:将每个桶中的元素收集起来,并将它们放回原来的数组中。
从每个桶中收集元素:
- 按顺序遍历每个桶。
- 将桶中的每个元素分别插入到原始数组中。

步骤 5:原始数组现在包含已排序的元素。
使用桶排序对给定的输入进行排序后的最终数组为 [0.12, 0.17, 0.21, 0.23, 0.26, 0.39, 0.68, 0.72, 0.78, 0.94]。

代码实现
#include <iostream>
#include <vector>
// Insertion sort function to sort individual buckets
void insertionSort(std::vector<float>& bucket)
{
for (int i = 1; i < bucket.size(); ++i)
{
float key = bucket[i];
int j = i - 1;
while (j >= 0 && bucket[j] > key)
{
bucket[j + 1] = bucket[j];
j--;
}
bucket[j + 1] = key;
}
}
// Function to sort arr[] of size n using bucket sort
void bucketSort(float arr[], int n)
{
// 1) Create n empty buckets
std::vector<float> b[n];
// 2) Put array elements in different buckets
for (int i = 0; i < n; i++)
{
int bi = n * arr[i];
b[bi].push_back(arr[i]);
}
// 3) Sort individual buckets using insertion sort
for (int i = 0; i < n; i++)
{
insertionSort(b[i]);
}
// 4) Concatenate all buckets into arr[]
int index = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < b[i].size(); j++)
{
arr[index++] = b[i][j];
}
}
}
// Driver program to test above function
int main()
{
float arr[] = {0.897, 0.565, 0.656, 0.1234, 0.665, 0.3434};
int n = sizeof(arr) / sizeof(arr[0]);
bucketSort(arr, n);
std::cout << "Sorted array is \n";
for (int i = 0; i < n; i++)
{
std::cout << arr[i] << " ";
}
return 0;
}
输出:

桶排序算法的复杂度分析:
时间复杂度:
- 最坏情况时间复杂度: O(n² )。最坏情况是指一个桶包含所有元素。在这种情况下,我们需要对所有元素执行插入排序,因此时间复杂度为 O(n² )。我们可以通过使用 O(n log n) 的算法(例如归并排序或堆排序)对各个桶进行排序,将最坏情况时间复杂度降低到 O(n log n)。但是,这种方法仅适用于桶中元素数量较少的情况,因为插入排序更适合处理小数组。
- 最佳情况时间复杂度: O(n + k) 最佳情况是每个桶中的元素数量相等。在这种情况下,每次调用插入排序的时间复杂度均为常数,因为每个桶中的元素数量都是恒定的(假设 k 与 n 成线性比例关系)。
辅助空间: O(n+k)

浙公网安备 33010602011771号