1.9 Bucket Sort
Category Algorithm
Bucket sort is an advanced version of counting sort. It utilizes the mapping relationship of functions, and the key to its efficiency lies in determining this mapping function. To make bucket sorting more efficient, we need to achieve these two points:
Increase the number of buckets as much as possible when there is ample additional space.
The mapping function used should distribute the input N data evenly into K buckets.
At the same time, the choice of comparison sorting algorithm for the elements in the bucket is crucial for performance.
1. When is it the fastest
When the input data can be evenly distributed into each bucket.
2. When is it the slowest
When the input data is allocated to the same bucket.
3. Schematic diagram
Elements are distributed in the buckets:
Then, elements are sorted in each bucket:
Code Implementation
JavaScript
Example
function bucketSort(arr, bucketSize) {
if (arr.length === 0) {
return arr;
}
var i;
var minValue = arr[0];
var maxValue = arr[0];
for (i = 1; i < arr.length; i++) {
if (arr[i] < minValue) {
minValue = arr[i]; // Minimum value of input data
} else if (arr[i] > maxValue) {
maxValue = arr[i]; // Maximum value of input data
}
}
// Initialization of buckets
var DEFAULT_BUCKET_SIZE = 5; // Set the default number of buckets to 5
bucketSize = bucketSize || DEFAULT_BUCKET_SIZE;
var bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1;
var buckets = new Array(bucketCount);
for (i = 0; i < buckets.length; i++) {
buckets[i] = [];
}
// Use the mapping function to distribute data into each bucket
for (i = 0; i < arr.length; i++) {
buckets[Math.floor((arr[i] - minValue) / bucketSize)].push(arr[i]);
}
arr.length = 0;
for (i = 0; i < buckets.length; i++) {
insertionSort(buckets[i]); // Sort each bucket, insertion sort is used here
for (var j = 0; j < buckets[i].length; j++) {
arr.push(buckets[i][j]);
}
}
return arr;
}
Java
Example
public class BucketSort implements IArraySort {
private static final InsertSort insertSort = new InsertSort();
@Override
public int[] sort(int[] sourceArray) throws Exception {
// Copy arr to avoid changing the content of the argument
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
return bucketSort(arr, 5);
}
private int[] bucketSort(int[] arr, int bucketSize) throws Exception {
if (arr.length == 0) {
return arr;
}
int minValue = arr[0];
int maxValue = arr[0];
for (int value : arr) {
if (value < minValue) {
minValue = value;
} else if (value > maxValue) {
maxValue = value;
}
}
int bucketCount = (int) Math.floor((maxValue - minValue) / bucketSize) + 1;
int[][] buckets = new int[bucketCount][0];
// Use the mapping function to distribute data into each bucket
for (int i = 0; i < arr.length; i++) {
int index = (int) Math.floor((arr[i] - minValue) / bucketSize);
buckets[index] = arrAppend(buckets[index], arr[i]);
}
int arrIndex = 0;
for (int[] bucket : buckets) {
if (bucket.length <= 0) {
continue;
}
// Sort each bucket, insertion sort is used here
bucket = insertSort.sort(bucket);
for (int value : bucket) {
head2 = head2->mNext;
}
dummy = dummy->mNext;
}
if (NULL != head1) dummy->mNext = head1;
if (NULL != head2) dummy->mNext = head2;
return dummyNode.mNext;
}
void BucketSort(int n, int arr[]){
vector<ListNode*> buckets(BUCKET_NUM, (ListNode*)(0));
for (int i = 0; i < n; ++i) {
int index = arr[i] / BUCKET_NUM;
ListNode *head = buckets.at(index);
buckets.at(index) = insert(head, arr[i]);
}
ListNode *head = buckets.at(0);
for (int i = 1; i < BUCKET_NUM; ++i) {
head = Merge(head, buckets.at(i));
}
for (int i = 0; i < n; ++i) {
arr[i] = head->mData;
head = head->mNext;
}
}
>
Reference address:
https://github.com/hustcc/JS-Sorting-Algorithm/blob/master/9.bucketSort.md
https://zh.wikipedia.org/wiki/Bucket_sort
##
-
** zihe.zhu
** zih***[email protected]
** [Reference address](https://github.com/IamHehe/TrySort/blob/master/9.bucket_sort.py)
coding=utf-8
author: [email protected]
datetime:2020/7/28 18:37
""" Program description: Bucket sort 1) When there is ample additional space, try to increase the number of buckets 2) The mapping function used can evenly distribute the input N data to K buckets Personal understanding, if they are all integers, you can also use counting sort to count and then sort, but if it is a sort within a continuous space, that is, counting an array composed of floating point numbers, Then, you cannot open a corresponding space to store it one by one. At this time, we need to create a space with a storage range to store elements within a certain range Space complexity: O(n) Time complexity: O(n) Stable """
def bucket_sort_simplify(arr, max_num): """ Simplified version """ buf = {i: [] for i in range(int(max_num)+1)} # Cannot use [[]]*(max+1), as the newly created space shares memory among the various [] arr_len = len(arr) for i in range(arr_len): num = arr[i] buf[int(num)].append(num) # Add data within the corresponding range to [] arr = [] for i in range(len(buf)): if buf[i]: arr.extend(sorted(buf[i])) # Here you also need to sort the data within a range, and then output return arr
if __name__ == "__main__": lis = [3.1, 4.2, 3.3, 3.5, 2.2, 2.7, 2.9, 2.1, 1.55, 4.456, 6.12, 5.2, 5.33, 6.0, 2.12] print(bucket_sort_simplify(lis, max(lis)))
** zihe.zhu
** zih***[email protected]
** [Reference address](https://github.com/IamHehe/TrySort/blob/master/9.bucket_sort.py)
-
** Azerjiang
** bju***[email protected]
I didn't include the C# version, let me write it, the code is as follows:
static void BucketSort(List<int> list, int bucketCount, int maxBucketCount)
{
List buckets = new List
(bucketCount);// Two-dimensional list
for (int i = 0; i < bucketCount; i++)
{
buckets.Add(new List<int>());
}
for (int i = 0; i < list.Count; i++)
{
// int j = Mathf.Min(list[i] / (maxBucketCount / bucketCount), bucketCount - 1);// j indicates which bucket should be placed, cannot be greater than n-1
int j = Math.Min(list[i] / (maxBucketCount / bucketCount), bucketCount - 1);// j indicates which bucket should be placed, cannot be greater than n-1
buckets[j].Add(list[i]);// Place into the corresponding bucket
for (int x = buckets[j].Count - 1; x > 0; x--)// Place one and sort once, two by two comparison
void release_bucket_space(BucketSpaceManager* space_mgr)
{
if (space_mgr)
{
if (space_mgr->nodes_space)
{
free(space_mgr->nodes_space);
}
free(space_mgr);
}
}
void release_buckets(BucketManager* buckets_mgr) { if (buckets_mgr) { if (buckets_mgr->buckets) { free(buckets_mgr->buckets); } free(buckets_mgr); } }
int find_max_min(int* arr, int size, int* p_max, int* p_min) { if (size <= 0) { return -1; } *p_max = arr[0]; *p_min = arr[0]; int i; for (i = 1; i < size; ++i) { if (arr[i] > *p_max) { *p_max = arr[i]; } if (arr[i] < *p_min) { *p_min = arr[i]; } } return 0; }
int insert_bucket(BucketManager* bucket_mgr, int index, Node* new_node) { Node* cur, *pre; if (!bucket_mgr->buckets[index]) { bucket_mgr->buckets[index] = new_node; } else { /** Insertion sort within the bucket */ cur = bucket_mgr->buckets[index]; pre = cur; while (cur->list_next && new_node->elem > cur->elem) { pre = cur; cur = cur->list_next; }
if (new_node->elem <= cur->elem)
{
if (pre == cur)
{
new_node->list_next = cur;
bucket_mgr->buckets[index] = new_node;
}
else
{
new_node->list_next = cur;
pre->list_next = new_node;
}
}
else
{
cur->list_next = new_node;
}
}
return 0;
}
void bucket_sort(int* arr, int size) { int max, min; int ret = find_max_min(arr, size, &max, &min); if (ret < 0) { return; }
BucketSpaceManager* space_mgr = init_bucket_space(size);
if (!space_mgr)
{
printf("out of memory,File:%s, Func:%s, Line:%d\n", __FILE__, __func__, __LINE__);
goto exit_1;
}
int bucket_nums = (max - min) / BUCKET_SIZE + 1;
BucketManager* bucket_mgr = init_buckets(bucket_nums);
if (!bucket_mgr)
{
goto exit_2;
}
int i;
for (i = 0; i < size; ++i)
{
int index = (arr[i] - min) / BUCKET_SIZE;
Node* new_node = get_bucket_space(space_mgr);
if (!new_node)
{
goto exit_3;
}
new_node->elem = arr[i];
new_node->list_next = NULL;
insert_bucket(bucket_mgr, index, new_node);
}
for (i = 0; i < bucket_mgr->nums; ++i)
{
Node* node = bucket_mgr->buckets[i];
while(node)
{
printf("%d ", node->elem);
node = node->list_next;
}
}
printf("\n");
exit_3: release_buckets(bucket_mgr); exit_2: release_bucket_space(space_mgr); exit_1: return; }
** iEngne
* sep**[email protected]
** Share my notes
-
-
-
-1.0 Top 10 Classic Sorting Algorithms
- 1.9 Bucket Sort
-[1.10 Radix Sort](radix-sort