桶排序
1 基本原理
1 核心思想:桶排序工作的原理是将数组分到有限数量的桶里。每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。最后依次连接各桶完成排序。
2 算法分析:
- 设置一个定量的数组当作空桶子。
- 遍历序列,并且把项目一个一个放到对应的桶子去。
- 对每个不是空的桶子分别进行排序。
- 从不是空的桶子里把项目再放回原来的序列中。
2 实例说明
如上图所示,以一组数据{29,25,3,49,9,37,21,43}为例,进行桶排序的算法演示:
- 获取数组中最大元素49,设定每个桶中元素数量为10, 则需要49/10=5个桶。
- 遍历原数组,依次将元素放入对应的桶中,如3,9放入第一个桶,29,25,21放入第三桶等。。。
- 分别对每个桶内元素进行排序,可得{3,9},{21,25,29},{37},{43,49}。
- 按顺序连接各桶,完成数组排序{3,9,21,25,29,37,43,49}。
3 代码实现
//桶排序
void BucketSort(vector<int> &a,int n)
{
double **p=new double*[10]; //十个指针,代表十个桶
for(int i=0;i<10;i++)
{
p[i]=new double[n/10 +1]; //设定每个桶中元素
}
int count[10]={0};
for(int i=0;i<n;i++)
{
double temp=a[i];
p[flag][count[flag]]=temp; //将元素放入对应桶中
int j=count[flag]++; //对应桶计数加1
//在桶内进行排序(插入排序)
for(;j>0 && temp<p[flag][j-1];j--)
{
p[flag][j]=p[flag][j-1];
}
p[flag][j]=temp;
}
//将全部元素在桶内进行排序后,进行重新连接
int k=0;
for(int i=0;i<10;i++)
{
for(int j=0;j<count[i];j++)
{
a[k++]=p[i][j];
}
}
//释放内存
for(int i=0;i<10;i++)
{
delete p[i];
p[i]=Null;
}
delete []p;
p=Null;
}
4 性能分析
1 时间复杂度:
对于N个待排数据,M个桶,平均每个桶[N/M]个数据的桶排序平均时间复杂度为:O(N)+O(M*(N/M)*log(N/M))=O(N+N*(logN-logM))=O(N+N*logN-N*logM)
当N=M时,即极限情况下每个桶只有一个数据时。桶排序的最好效率能够达到O(N)。
桶排序的平均时间复杂度为线性的O(N+C),其中C=N*(logN-logM)。
- 2 空间复杂度:
桶排序的空间复杂度 为O(N+M),如果输入数据非常庞大,而桶的数量也非常多,则空间代价较大。
- 3 算法稳定性:
桶排序是稳定的算法。