//bucket sort
//现在假设我有一堆蛋,包括麻雀蛋、鸡蛋、恐龙蛋,现在我要将这几种蛋排序下序;
//有点常识就知道,这三种类别的蛋大小是不一样的,而且每一类蛋的大小也是有区别的,现在我对这三种蛋进行排序,我是这样排的:
//准备三个桶,把同一类别的蛋放到同一个桶中,然后对每一个桶内的蛋进行排序,然后按顺序从三个桶中取出相应蛋排序;
//即,从放有麻雀蛋的桶里取出所有麻雀蛋,因为已经有序,直接取出即可,然后再将鸡蛋取出,最后取出恐龙蛋,排序完成;
//桶排序即先将大小相近的蛋(或“同一类蛋”)放入到同一个桶中,然后对桶内的蛋进行排序,由于每个桶内蛋的数量比较有限,所以排序效率较高
//桶排序是一种时间复杂度为O(n)的排序方法,但并不意味着它有多优秀,上帝打开一扇门的同时也会关上一扇窗
//桶排序的局限如下:
//1)桶排序耗用较大的辅助空间,所需要的辅助空间一般与被排序的数列的最大值与最小值有关;
//2)听到“桶”,很容易联想到哈希表,因为哈希表的冲突解决方法之一开链法也相当于一个个桶,事实上,这两种桶的原理是基本相同的;
//3)并非所有数列都适合桶排序,桶排序适合分布比较均匀的数列,如1,2,3,6,4,像0,999,558,10000这种就不太适合
//4)桶排序是一种稳定的排序算法
//5)桶排序需要维护一个链表,但也有一类简单的桶排序算例如下,所有不同键值是放在不同的桶当中的,所以不用维护链表,当然,下面这种方法也不再稳定
#include<vector>
#include<iostream>
using namespace std;
void bucketSort(vector<int>& vec)
{
int length=vec.size();
vector<int> buckets(length,0);//准备一堆桶,容器的下标即待排序数组的键值或键值经过转化后的值
//此时每个桶中都是没有放蛋的,所以都是0
for(int i=0;i<length;++i)
{
buckets[vec[i]]++;//把每个蛋放入到对应的桶中
}
int index=0;
for(int i=0;i<length;++i)
{//把蛋取出,空桶则直接跳过
for(int j=0;j<buckets[i];j++)
{
vec[index++]=i;
}
}
}
//上例是直接将键值作为桶下标的程序,没有经过转化
int main()
{
int a[10]={0,2,5,6,3,2,5,9,5,2};
vector<int> vec(a,a+10);
bucketSort(vec);
for(int i=0;i<vec.size();++i)
{
cout<<vec[i]<<" ";
}
return 0;
}