桶排序算法
对于待排的数组,从前往后扫描,对于索引i的值,计数数组对应的索引+1得到计数桶。然后对于计数桶,从前往后累加得到累加桶。对于待排数组,从后往前依次取出值作为索引在累加桶中找到对应的值,该值减一得到的结果就是排序后桶应该在的位置。反复如此直到处理完待排序数组。
索 引: 0 1 2 3 4 5 6 7 8 9
原数组: 7 3 8 9 6 1 8 1 2
计数桶: 0 2 1 1 0 0 1 1 2 1
累计桶: 0 2 3 4 4 4 5 6 8 9
因为原始数组最大值为9,创建一个范围0-9(m)
用来统计各个元素出现的次数的计数桶
。可以看到原始数组中1出现了两次,计数桶index=1
的地方值为2,累计桶就是对index(如4)
前面的所有元素求和0+2+1+1+0=4
。
性能
- 时间代价 Θ(n+m) Θ ( n + m ) ,需要扫描原始数组统计次数 n n ,对 的前面的数求和。
- 空间代价 Θ(n+m) Θ ( n + m ) , n n 用来存放临时排序结果,存放 个计数器。
- 稳定
#include <iostream>
using namespace std;
void print(int *a,int n)
{
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<"\n";
}
int main()
{
int a[] = {7,3,8,9,6,1,8,1,2};
int n = sizeof(a)/ sizeof(a[0]);
int max = 0;
for(int i=0;i<n;i++)
{
if(a[i]>max)
max = a[i];
}
// cout<<"新数组最大长度为:"<<max;
int *countbuck = new int[max+1];
int *totalbuck = new int[max+1];
int *sortbuck = new int[max+1];
for(int i=0;i<n;i++)
{
if(a[i]!=0)
countbuck[a[i]]+=1;
}
cout<<"计数桶: ";
print(countbuck,max+1);
int sum = 0;
for(int i=0;i<max+1;i++)
{
sum += countbuck[i];
totalbuck[i] = sum;
}
cout<<"累计桶:";
for(int i=max-1;i>0;i--)
{
int temp = a[i];
sortbuck[totalbuck[temp]--] = temp;
}
print(sortbuck,max+1);
delete [] countbuck;
delete [] totalbuck;
delete [] sortbuck;
}