箱排序的变种。为了区别于上述的箱排序,姑且称它为桶排序(实际上箱排序和桶排序是同义词)。
算法
桶排序的思想是把[0,1)划分为n个大小相同的子区间,每一子区间是一个桶。而后将n个记录分配到各个桶中。由于关键字序列是均匀分布在[0,1)上的,因此通常不会有不少个记录落入同一个桶中。因为同一桶中的记录其关键字不尽相同,因此必须采用关键字比较的排序方法(一般用插入排序)对各个桶进行排序,而后依次将各非空桶中的记录链接(收集)起来便可。spa
注意:指针
这种排序思想基于如下假设:假设输入的n个关键字序列是随机分布在区间[0,1)之上。若关键字序列的取值范围不是该区间,只要其取值均非负,咱们总能将全部关键字除以某一合适的数,将关键字映射到该区间上。但要保证映射后的关键字是均匀分布在[0,1)上的。code
伪代码算法为:排序
void BucketSon(R)
{ //对R[0..n-1]作桶排序,其中0≤R[i].key<1(0≤i<n)
for(i=0,i<n;i++) //分配过程.
将R[i]插入到桶B[「n(R[i].key)」]中; //可插入表头上
for(i=0;i<n;i++) //排序过程
当B[i]非空时用插人排序将B[i]中的记录排序;
for(i=0,i<n;i++) //收集过程
若B[i]非空,则将B[i]中的记录依次输出到R中;
}
注意:
class
实现时需设置一个指针向量B[0..n-1]来表示n个桶。但由于任一记录R[i]的关键字知足:0≤R[i].key<1(0≤i≤n-1),因此必须将R[i].key映射到B的下标区间[0,n-1)上才能使R[i]装入某个桶中,这可经过└n*(R[i].key)┘来实现。方法
桶排序的平均时间复杂度是线性的,即O(n)。但最坏状况仍有多是O(n2)。时间
箱排序只适用于关键字取值范围较小的状况,不然所需箱子的数目m太多致使浪费存储空间和计算时间。co
【例】n=10,被排序的记录关键字ki取值范围是0到99之间的整数(36,5,16,98,95,47, 32,36,48)时,要用100个箱子来作一趟箱排序。(即若m=n2时,箱排序的时间O(m+n)=O(n2))。void