桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到这两点:
- 在额外空间充足的情况下,尽量增大桶的数量
- 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中
同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。
原理去b站看视频,通俗易懂,这里只供参考代码如何实现
#include<iostream>
using namespace std;
#define bucket_num 3
//该程序实现的桶排序所用链表带头节点
typedef int ElemType;
struct Node
{
ElemType data;
Node* next;
};
//链表初始化
Node* InitList()
{
Node* head = new Node;
head->next = nullptr;
return head;
}
//释放链表
void DestroyList(Node* head)
{
if (head == nullptr) return;
Node* temp = nullptr;
while (head!=nullptr)
{
temp = head->next;
delete head;
head = temp;
}
}
// 把元素有序的插入链表中,返回值:false-失败;true-成功。
bool PushOrder(Node* head, ElemType elem)
{
if (head == nullptr)return false;
Node* temp = new Node;
temp->data = elem;
Node* p = head;
while (p->next!=nullptr)
{
//如果elem小于p->next->data,就插在p的后面
if (elem < p->next->data)
{
temp->next = p->next;
p->next = temp;
return true;
}
p = p->next;
}
p->next = temp;
temp->next = nullptr;
return true;
}
//合并两个升序链表head1和head2成一个升序链表head
void MergeList(Node* head1, Node* head2, Node* head)
{
if (!head1 || !head2) return;
Node* p1 = head1->next;
Node* p2 = head2->next;
Node* tail = head;
while (p1 && p2)
{
//取p1和p2的较小值,追加到head的尾结点
if (p1->data <= p2->data)
{
tail->next = p1;
p1 = p1->next;
}
else
{
tail->next = p2;
p2 = p2->next;
}
tail = tail->next;
}
if (p1 == nullptr)
tail->next = p2;//把p2以及后面的结点追加到head3的后面
if (p2 == nullptr)
tail->next = p1;//把p1以及后面的结点追加到head3的后面
// 链表head1和head2的结点已全部转移给了和head,需置空,否则DestroyList()时会引起重复释放结点。
head1->next = head2->next = nullptr;
}
//桶排序函数
void bucket_sort(ElemType arr[], size_t len)
{
// 分配桶头结点的结构体数组。
Node* buckets = new Node[bucket_num];
// 初始化桶,把头结点的next指针置为空。
for (int i = 0; i < bucket_num; i++) buckets[i].next = nullptr;
// 把数组arr全部的元素放入桶中。
for (int i = 0; i < len; i++)
{
PushOrder(&buckets[arr[i] % bucket_num], arr[i]);
}
//合并链表
Node temp;
temp.next = nullptr;
Node L;
L.next = nullptr;
for (int i = 0; i < bucket_num; i++)
{
MergeList(&L , &buckets[i], &temp);
swap(L.next, temp.next);
}
//把链表的值依次赋值给数组
Node* p = L.next;
for (int i = 0; i < len; i++)
{
arr[i] = p->data;
p = p->next;
}
DestroyList(L.next);
delete[] buckets;
}
int main(){
ElemType arr[] = { 0,9,8,100,6,5,4 };
for (auto it : arr)
{
cout << it << " ";
}
cout << endl;
bucket_sort(arr, 7);
for (auto it : arr)
{
cout << it << " ";
}
cout << endl;
system("pause");
return 0;
}