桶排序,与计数排序假设思想类似,计数排序假设输入是一个小范围内的整数构成的,而桶排序假设输入是一个随机过程,该过程将元素均匀独立地分布在[0,1)区间上;
桶排序思想
(1)最大的思想就是要均匀分布,就是[0,1)区间只是狭义上的分布;其实有很多排序可以转换成[0,1)区间的思想;例如:要排序区间数值范围为[0,10000)的数,我们把该区间分割成100个桶,桶的范围一次是[0,100),[100,200),.........[900,1000),[9900,10000);
(2)这样的区间分割其实也是符合均匀分布的;
桶排序步骤
(1)先把[0,1)区间划分成相同大小的子区间,或称为桶;
(2)将n个输入分布到桶中,因为输入数均匀且独立在[0,1),因此不会有很多数落在一个桶的情况;
(3)先对各个桶中的数进行排序,对桶内排序,可用插入排序,快速排序等;
(4)然后把各次序,把各桶中的元素列出来即可;
(5)可证明时间复杂度为O(n),空间复杂度为O(1);
桶排序实现
输入:输入的整数区间范围[0,1000),随机产生100个数;
注:(1)注意C++中的引用传递,push_back()的对象的生命周期;
(2)在对桶内的排序使用了C++标准库中自带的sort()算法,没有自己编写排序算法;
#include<iostream>
#include<vector>
#include<algorithm>
#include<time.h> //this is in the C Library
#include<stdlib.h>//this is in the C Library
using namespace std;
#define ARRAY_LENGTH (100)
#define MAX_NUMBER (1000)
#define BARREL_NUMBERS (10)
void output(vector<int>& seeds)
{
size_t i;
for(i = 0; i < ARRAY_LENGTH; i++){
cout<<seeds[i]<<' ';
}
cout<<endl;
}
void out_sort(vector<vector<int> >& barrel)
{
size_t i;
size_t j;
for(i = 0; i < BARREL_NUMBERS; i++)
for(j = 0; j < barrel[i].size(); j++)
cout<<barrel[i][j]<<' ';
cout<<endl;
}
void gendrate_seeds(vector<int>& seeds)
{
srand( (unsigned)time( NULL ) );
int i;
for(i = 0; i < ARRAY_LENGTH; i++){
seeds.push_back( rand()%MAX_NUMBER);
}
}
int obtain_index_of_barrel(int temp)
{
int x = MAX_NUMBER / BARREL_NUMBERS;
int count = 0;
while(temp >= x){
x = 2 * x;
count++;
}
return count;
}
void assign_barrel(vector<int>& seeds, vector<vector<int> >& barrel)
{
size_t i;
vector<int> temp;//very impotant
for(i = 0; i < BARREL_NUMBERS; i++){
barrel.push_back(temp);
}
for(i = 0; i < ARRAY_LENGTH; i++){
barrel[obtain_index_of_barrel(seeds[i])].push_back(seeds[i]);
}
for(i = 0; i < BARREL_NUMBERS; i++){
stable_sort(barrel[i].begin(), barrel[i].end());
}
}
int main(void)
{
vector<int> seeds;
vector<vector<int> > barrel;
gendrate_seeds(seeds);
cout<<"pre state:\n";
output(seeds);
cout<<"\n\nsort state:\n";
assign_barrel(seeds, barrel);
out_sort(barrel);
return 0;
}