在本教程中,您将学习桶排序算法的工作方式。此外,您还将找到使用C语言的示例。
桶排序是一种排序技术,它首先将元素划分为几个称为桶的组,从而对元素进行排序。每个桶都可以分别使用合适自己的算法或递归调用相同的算法对桶内的元素进行排序。
创建几个桶。每个桶都装满了特定范围的元素。桶中的元素可以使用任何算法进行排序。最后,集合桶内的元素,得到排序后的数组。
桶排序过程可以理解为一种分散-聚集方法。首先将元素分散到桶中,然后对桶中的元素进行排序。最后,集合排序后的元素。(感觉原文这两段啰嗦了)
桶排序如何工作?
- 假设输入数组为:
创建一个大小为10的数组。此阵列的每个插槽都用作存储元素的桶。
- 将元素从数组中插入到桶中。根据桶的范围插入元素。
在示例代码中,桶的范围分别为0到1,1到2,2到3,… …(n-1)至n。
假设输入元素是 0.23,乘以10(即 0.23*10=2.3)。然后,它被转换成一个整数(即2.3≈2)。最后,0.23被插入桶2。
同样,0.25也插入到同一个桶中。每次取浮点数的下限值。
如果我们将整数作为输入,则必须将其除以间隔(此处为10)才能获得下限值。
同样,其他元素也会插入各自的桶中。
- 可以使用任何稳定的排序算法对每个桶的元素进行排序。在这里,我们使用了快速排序(内置函数)。
- 集合每个桶中的元素。
通过遍历桶并在每次循环中将单个元素插入原始数组来完成此操作。一旦将桶中的元素复制到原始数组中,该元素将被擦除。
桶排序算法
bucketSort()
create N buckets each of which can hold a range of values
for all the buckets
initialize each bucket with 0 values
for all the buckets
put elements into buckets matching the range
for all the buckets
sort elements in each bucket
gather elements from each bucket
end bucketSort
C示例
// Bucket sort in C
#include <stdio.h>
#include <stdlib.h>
#define NARRAY 7 // Array size
#define NBUCKET 6 // Number of buckets
#define INTERVAL 10 // Each bucket capacity
struct Node {
int data;
struct Node *next;
};
void BucketSort(int arr[]);
struct Node *InsertionSort(struct Node *list);
void print(int arr[]);
void printBuckets(struct Node *list);
int getBucketIndex(int value);
// Sorting function
void BucketSort(int arr[]) {
int i, j;
struct Node **buckets;
// Create buckets and allocate memory size
buckets = (struct Node **)malloc(sizeof(struct Node *) * NBUCKET);
// Initialize empty buckets
for (i = 0; i < NBUCKET; ++i) {
buckets[i] = NULL;
}
// Fill the buckets with respective elements
for (i = 0; i < NARRAY; ++i) {
struct Node *current;
int pos = getBucketIndex(arr[i]);
current = (struct Node *)malloc(sizeof(struct Node));
current->data = arr[i];
current->next = buckets[pos];
buckets[pos] = current;
}
// Print the buckets along with their elements
for (i = 0; i < NBUCKET; i++) {
printf("Bucket[%d]: ", i);
printBuckets(buckets[i]);
printf("\n");
}
// Sort the elements of each bucket
for (i = 0; i < NBUCKET; ++i) {
buckets[i] = InsertionSort(buckets[i]);
}
printf("-------------\n");
printf("Bucktets after sorting\n");
for (i = 0; i < NBUCKET; i++) {
printf("Bucket[%d]: ", i);
printBuckets(buckets[i]);
printf("\n");
}
// Put sorted elements on arr
for (j = 0, i = 0; i < NBUCKET; ++i) {
struct Node *node;
node = buckets[i];
while (node) {
arr[j++] = node->data;
node = node->next;
}
}
return;
}
// Function to sort the elements of each bucket
struct Node *InsertionSort(struct Node *list) {
struct Node *k, *nodeList;
if (list == 0 || list->next == 0) {
return list;
}
nodeList = list;
k = list->next;
nodeList->next = 0;
while (k != 0) {
struct Node *ptr;
if (nodeList->data > k->data) {
struct Node *tmp;
tmp = k;
k = k->next;
tmp->next = nodeList;
nodeList = tmp;
continue;
}
for (ptr = nodeList; ptr->next != 0; ptr = ptr->next) {
if (ptr->next->data > k->data)
break;
}
if (ptr->next != 0) {
struct Node *tmp;
tmp = k;
k = k->next;
tmp->next = ptr->next;
ptr->next = tmp;
continue;
} else {
ptr->next = k;
k = k->next;
ptr->next->next = 0;
continue;
}
}
return nodeList;
}
int getBucketIndex(int value) {
return value / INTERVAL;
}
void print(int ar[]) {
int i;
for (i = 0; i < NARRAY; ++i) {
printf("%d ", ar[i]);
}
printf("\n");
}
// Print buckets
void printBuckets(struct Node *list) {
struct Node *cur = list;
while (cur) {
printf("%d ", cur->data);
cur = cur->next;
}
}
// Driver code
int main(void) {
int array[NARRAY] = {
42, 32, 33, 52, 37, 47, 51};
printf("Initial array: ");
print(array);
printf("-------------\n");
BucketSort(array);
printf("-------------\n");
printf("Sorted array: ");
print(array);
return 0;
}
复杂度
- 最坏情况复杂度:O( n 2 n^2 n2)
当数组中有取值相近的元素时,它们很可能被放置在同一个桶中。这可能导致某些桶的元素数多于其他桶。
这使得复杂度取决于对桶内元素进行排序的排序算法。
当元素的顺序相反时,复杂性会变得更糟。如果使用插入排序对桶内元素进行排序,则时间复杂度变为O( n 2 n^2 n2)。 - 最佳情况复杂度:O(n+k)
当元素均匀分布在桶中,每个桶中的元素数量几乎相等时,就会发生这种情况。
如果桶中的元素已经被排序,那么复杂度会变得更好。
如果使用插入排序对桶内元素进行排序,那么在最佳情况下,总体复杂度将是线性的,即O(n+k)。O(n)是生成桶的复杂度,O(k)是在最佳情况下,使用具有线性时间复杂度的算法对桶的元素进行排序的复杂度。 - 平均情况复杂度:O(n)
当元素在数组中随机分布时会发生这种情况。即使元素分布不均匀,桶排序也以线性时间运行。
桶排序应用
在下列情况下使用桶排序:
- 输入在一定范围内均匀分布
- 存在浮点值
参考文档
[1]Parewa Labs Pvt. Ltd.Bucket Sort Algorithm[EB/OL].https://www.programiz.com/dsa/bucket-sort,2020-01-01.