排序算法千万种,但最容易和简单的排序算法桶排序当仁不让,我们今天就来了解一下它,看它如何使用,适用什么场景。
一、概念
桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(O(N)。但桶排序并不是比较排序,他不受到 O(n log n) 下限的影响。
我们今天学习的不是严格意义上的桶排序,比它要简单,但原理相同,所以也称为桶排序。
桶排序是一种空间换时间的算法,利用和数值范围一样大的数组来存储数字,下标代表数组元素,数组保存元素出现次数。假如0~10范围的数字进行排序,那么:
这时我们可以看到桶的作用就是标记每个数出现的次数,那么我们在排序时,只需要输出桶内不为0的数组下标即可。
二、特点
- 时间复杂度:桶的个数为m个,待排序数字为n个,则时间复杂度为O(N+M)。最好的情况为O(M+N),最坏的情况就是桶内元素出现的次数和数值范围相近:O(N^2)
- 空间复杂度:需要申请空间为:S(N+M)
- 是一种外排序,需要在磁盘上排序。
- 是一种稳定排序,一样的元素前后顺序不会变
- 优点:速度很快。
- 缺点:
(1)只能对数字进行排序,如果是根据数字输出另一个信息,如对应的名字,则失败,它只是对数字排序了,并不知道数字后面对应谁。
(2)非常浪费空间,数值范围1000000,但只有5个数,你还是要申请1000000大小的数组。
(3)只能给整数排序,因为数组下标是整数,所以就不能给小数等排序。
三、例题
我们举几个例子:
1.题目: 我们现在需要对学生成绩进行排序,满分10分,分别是cc同学5分,dd同学3分,ss同学5分,bb同学·8分,zz同学2分,将这五位同学的成绩进行排序,从小到大输出。
输出: 2 3 5 5 8
- 我们桶排序得到次数
- 打印时根据数组中次数进行打印。
void BucketSort(vector<int>& nums)
{
vector<int> res(10,0);
//进行桶标记
for(int i=0;i<nums.size();i++)
{
res[nums[i]]+=1;//存入次数
}
//打印
for(int i=0;i<res.size();i++)
{
for(int j=0;j<res[i];j++)//打印重复的
{
cout<<i<<" ";//打印元素
}
}
}
int main()
{
vector<int> nums;
nums.push_back(5);
nums.push_back(3);
nums.push_back(5);
nums.push_back(2);
nums.push_back(8);
BucketSort(nums);
}
我们可以看到如果让我们输出排序好的成绩和名字,那么桶排序无法解决。
加油哦!💪。