查了很多文章,桶排序思想简单,实现起来有点复杂,记录一下桶排序。
一、桶排序是什么?
桶排序(又称箱排序)是一种基于分治思想、效率很高的排序算法,理想情况下对应的时间复杂度为 O(n)。
二、实现思路
1. 分组
将待排数据进行分组,如下图,将这些数组按范围分到各个桶中,此时每个桶中的数据是无序的,我们还需要为每个桶中的数据排序。每个桶中的排序算法选择至关重要。
看了很多教学文章,说每个桶中的数据是用链表存储的,可能为了减少开销吧,不知道用vector存行不行~
2. 桶内排序
对每个桶内的数据进行排序。
3. 合并
将排好的各个桶合并。
实现:
```cpp
// 桶排序.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <vector>
using namespace std;
//每个桶中的元素以链表的方式存在
typedef struct Node {
Node(int i = 0) :data(i), next(NULL) {}
int data;
Node* next;
}Node;
Node* insert(Node* head, int val) { //把变量val按序插入到链表中
Node* newNode = new Node(val); //为变量开辟内存
Node *pre,*curr;
Node dummy;
dummy.next = head;
pre = &dummy;
curr = head;
while (curr != nullptr && val > curr->data) { //变量如果大于当前节点的值,说明变量不应该在此刻插入
pre = curr;
curr = curr->next;
}
//如果变量值小于等于当前节点的值,就把这个值插入到当前节点前面
newNode->next = curr;
pre->next = newNode;
return dummy.next;
}
Node* merge(Node* head1, Node* head2) { //把两个链表连在一起,返回的是连接后的链表
Node* dummy = new Node(0);
Node* p=dummy;
while (head1 != nullptr && head2 != nullptr) {
if (head1->data < head2->data) {
p->next = head1;
p = p->next;
head1 = head1->next;
}
else {
p->next = head2;
p = p->next;
head2 = head2->next;
}
}
if (head1 != nullptr) p->next = head1;
if (head2 != nullptr) p->next = head2;
return dummy->next;
}
void bucketSort(vector<int> arr) { //对vec中的值进行桶排序
int n = arr.size();
int bucketNum = 10;
vector<Node*> Bucket(bucketNum, (Node * )(0));//每个桶中有一个链表
for (int i = 0; i < n; i++) {
int index = arr[i] ;//找到当前元素应该在哪个桶中
Node* head = Bucket[i]; //定位到桶
Bucket[i] = insert(head, arr[i]);//把当前元素插入到该桶所在的链表中
}
Node* res=Bucket[0];
for (int i = 1; i < bucketNum; i++) {
res = merge(res, Bucket[i]);
}
for (int i = 0; i < n; i++) {
arr[i] = res->data;
res = res->next;
cout << arr[i] << endl;
}
}
int main() {
vector<int> arr{ 4,1,7,6,3,5,0 };
bucketSort(arr);
}