桶排序的思想有点像计数排序,又有点像快速排序,还用到一点hash的东西,值得仔细琢磨。
具体做法如下,按照某种hash函数,将数据映射到不同的桶中,使用hash是因为我们要保证每个数据的映射过程应该在常数时间内完成。映射完成后,每个桶中的数据相比于其他桶都是有序的(也就是相邻的桶有严格的顺序),这个就有点像快速排序了(可以把那里看成是两个桶)。之后可以对每个桶内的数据用其他的排序方法排序。当然也可以对桶内的数据继续进行桶排序,但如果hash函数选的好的话,桶内的数据直接采用其他的排序方法应该就能达到比较高的时间复杂度了。排序完毕后按照桶的顺序依次输出每个桶中的元素即可。代码如下(假设数据范围为[0,100)):
// bucketSort.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <cmath>
#include <ctime>
#define BUCKET_NUM 10 //桶的数量
using namespace std;
void inserSort(vector<int> &a)
{
int i, j;
for (j = 1; j<a.size(); j++)
{
i = j - 1;
int temp = a[j];
//找到插入位置
while (i >= 0 && temp<a[i])
{
a[i + 1] = a[i];
--i;
}
//将元素插入
a[i + 1] = temp;
}
}
vector<int> bucketSort(vector<int> &v)
{
vector<vector<int>> bucket(10);
for (int i = 0; i < v.size(); i++)
{
bucket[v[i] / 10].push_back(v[i]); //入桶
}
//桶内采用选择排序
for (int i = 0; i < bucket.size(); i++)
inserSort(bucket[i]);
vector<int> ans;
for (int i = 0; i < bucket.size(); i++)
for (int j = 0 ; j < bucket[i].size(); j++)
ans.push_back(bucket[i][j]);
return ans;
}
int main()
{
srand(time(NULL));
vector<int> a;
for (int i = 0; i < 20; i++)
a.push_back(rand() % 100);
auto ans = bucketSort(a);
for (auto i : ans)
cout << i << endl;
system("pause");
return 0;
}
运行结果: