重要的排序算法——桶排序

桶排序是 OI 中常用的算法。这篇题解/笔记将会详细地讲解桶排序的原理、实现过程,以及桶排序的应用。

1.桶排序的定义

桶排序(英文:Bucket sort)是排序算法的一种,适用于待排序数据值域较大但分布比较均匀的情况。
桶排序的时空复杂度均为 \(O(m)\),( m 为值域大小)是较为高效的排序方法。
在 m 接近于 n 时,桶排序的时空复杂度是所有排序算法中最优的,为 \(O(n)\)

2.桶排序的思路

桶排序按下列步骤进行:

  1. 设置一个定量的数组当作空桶;
  2. 遍历序列,并将元素一个个放到对应的桶中;
  3. 对每个不是空的桶进行排序;
  4. 从不是空的桶里把元素再放回原来的序列中。

如果使用稳定的内层排序,并且将元素插入桶中时不改变元素间的相对顺序,那么桶排序就是一种稳定的排序算法。

3.桶排序的实现

#include<bits/stdc++.h>
using namespace std;
int n,a[100010],t[10000005];
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i],t[a[i]]++;
	for(int i=1;i<=10000000;i++)for(int j=1;j<=t[i];j++)cout<<i<<' ';
}   

一般桶排最高1e7,1e8都得看题目的脸色(((
这在模板里拿到了60分。
难道这就是极限了吗?
由于本题数据范围为1e9,直接桶排无法通过,不妨使用一些小技巧。
用一个桶,存它的前五位。
对于每五位,再次桶排。
实现如下:

#include<iostream>
#include<vector>
using namespace std;
int n,a,t[10005];
vector<int> b[100005];
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a,b[a/10000].push_back(a%10000);
	for(int i=0;i<=100000;i++){
        for(int j=0;j<b[i].size();j++)t[b[i][j]]++;
		if(!b[i].empty())for(int j=0;j<10000;j++)while(t[j])cout<<i*10000+j<<' ',t[j]--;
	}
}   

复杂度为 \(O(m)\)
这就是极限了吗?
是的。

4.结语

桶排序作为一种在值域较小时较高效的排序算法,不仅可以解决值域较小的排序问题,还可以通过一些技巧解决一些较为复杂的问题。
同时,如果题目给出了值域较小的部分分,桶排序也是骗分的利器。
因此,桶排序还是蛮有用的orz
感谢你阅读到了现在,觉得有用的话,不妨点个赞吧!

posted @ 2025-05-03 15:09  yzc_is_SadBee  阅读(99)  评论(0)    收藏  举报