桶排序
桶排序是計數(shù)排序的升級版。它利用了函數(shù)的映射關系,高效與否的關鍵就在于這個映射函數(shù)的確定懦傍。為了使桶排序更加高效丙笋,我們需要做到這兩點:
- 在額外空間充足的情況下谢澈,盡量增大桶的數(shù)量
- 使用的映射函數(shù)能夠將輸入的 N 個數(shù)據(jù)均勻的分配到 K 個桶中
同時,對于桶中元素的排序御板,選擇何種比較排序算法對于性能的影響至關重要锥忿。
1.什么時候最快
當輸入的數(shù)據(jù)可以均勻的分配到每一個桶中。
2.什么時候最慢
當輸入的數(shù)據(jù)被分配到了同一個桶中稳吮。
3.示意圖
元素分布在桶中:
然后缎谷,元素在每個桶中排序:
4.代碼
#include <stdio.h>
#include <stdlib.h>
#define BUCKET_NUM 10
struct ListNode {
struct ListNode* next;
int data;
};
struct ListNode*
insert(struct ListNode *head, int value)
{
struct ListNode dummyNode;
struct ListNode *newNode = (struct ListNode *)malloc(sizeof(struct ListNode));
struct ListNode *pre, *curr;
newNode->data = value;
dummyNode.next = head;
pre = &dummyNode;
curr = head;
while (curr != NULL && curr->data <= value) {
pre = curr;
curr = curr->next;
}
newNode->next = curr;
pre->next = newNode;
return dummyNode.next;
}
struct ListNode*
merge(struct ListNode *head1, struct ListNode *head2)
{
struct ListNode dummyNode;
struct ListNode *dummy = &dummyNode;
while (head1 != NULL && head2 != NULL) {
if (head1->data <= head2->data) {
dummy->next = head1;
head1 = head1->next;
} else {
dummy->next = head2;
head2 = head2->next;
}
dummy = dummy->next;
}
if (head1 != NULL) dummy->next = head1;
if (head2 != NULL) dummy->next = head2;
return dummyNode.next;
}
void
bucket_sort(int n, int arr[])
{
struct ListNode* buckets[BUCKET_NUM] = {0};
int i;
for (i = 0; i < n; ++i) {
int index = arr[i] / BUCKET_NUM;
struct ListNode *head = buckets[index];
buckets[index] = insert(head, arr[i]);
}
struct ListNode *head = buckets[0];
for (i = 1; i < BUCKET_NUM; ++i) {
head = merge(head, buckets[i]);
}
for (i = 0; i < n; ++i) {
arr[i] = head->data;
head = head->next;
}
}
int
main()
{
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr) / sizeof(*arr);
bucket_sort(len, arr);
int i;
for (i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
部分內容轉載于菜鳥教程
2021.01.29 16:47 深圳