目录
哈喽
穿梭门
效果
桶排序是什么
再简单点说
再再简单点说
思路
确定“分桶”个数
复杂度分析
c++代码实现
python版代码(嘿嘿,没想到吧)
最后
这次来发一下桶排序,它的时间复杂度低,代码也不难
二分算法
堆排序
就是排序
所以说,还是比较简单滴
桶排序是计数排序的升级版,也是分治算法。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。简言之,将值为i的元素放入i号桶,最后依次把桶里的元素倒出来。
怎么样,是不是很“简单”?
还有这张一看就头疼的图
桶排序的基本思想是假设数据在[min,max]之间均匀分布,其中min、max分别指数据中的最小值和最大值。那么将区间[min,max]等分成n份,这n个区间便称为n个桶。将数据加入对应的桶中,然后每个桶内单独排序。由于桶之间有大小关系,因此可以从大到小(或从小到大)将桶中元素放入到数组中。
简单说,你有一个数组1 , 3 , 7 , 77 ,100 ,234
比如,
你把一位数、两位数和三位数分到3个桶里,
各自排完序再合到一起
排序前:1 , 3 , 7 , 77 ,100 ,234
一位数:1、7、3
两位数:77
三位数:100、234
排序后:
一位数:1、3、7
两位数:77
三位数:100、234
合起来:1、3、7、77、100、234
1.设置一个定量的数组当作空桶子。
2.寻访序列,并且把项目一个一个放到对应的桶子去。
3.对每个非空的桶子进行排序。
4.从不是空的桶子里把项目再放回原来的序列中。
假如要对数组arr={ 2,0,1,6,8,10,5,99,87,333,2,0,1 }排序,假设需要桶的个数为bucketNum=std::ceil(size/3),向上取整,反之桶个数不够映射时越界。
桶排序实际上只需要遍历一遍所有的待排序元素,然后依次放入指定的位置,如果加上输出排序的时间,那么需要遍历所有的桶,时间复杂度为O(n+m),其中n为待排序元素的个数,m为桶的个数,这时相当快的排序算法,但是,对于空间的小号来说太大了。当n越大,空间浪费就越大,所以,如果数据跨度过大,桶排序并不适用跨度范围大的排序。
直接放代码,如果你报错了,就把前面的万能头文件改了
c++版(devc++无报错无警告)
#include
using namespace std;
// 打印数组
void print_array(int *arr, int n) {
if(n==0){
printf("ERROR: Array length is ZERO\n");
return;
}
printf("%d", arr[0]);
for (int i=1; i maxValue) // 输入数据的最大值
maxValue = arr[i];
// 设置10个桶,依次0,1,,,9
const int bucketCnt = 10;
vector buckets[bucketCnt];
// 桶的大小bucketSize根据数组最大值确定:比如最大值99, 桶大小10
// 最大值999,桶大小100
// 根据最高位数字映射到相应的桶,映射函数为 arr[i]/bucketSize
int bucketSize = 1;
while (maxValue) { //求最大尺寸
maxValue /= 10;
bucketSize *= 10;
}
bucketSize /= 10; //桶的个数
// 入桶
for (int i=0; i0; j--) {
if (buckets[idx][j]
def bucketSort(nums):
# 选择一个最大的数
max_num = max(nums)
# 创建一个元素全是0的列表, 当做桶
bucket = [0]*(max_num+1)
# 把所有元素放入桶中, 即把对应元素个数加一
for i in nums:
bucket[i] += 1
# 存储排序好的元素
sort_nums = []
# 取出桶中的元素
for j in range(len(bucket)):
if bucket[j] != 0:
for y in range(bucket[j]):
sort_nums.append(j)
return sort_nums
nums = [5,6,3,2,1,65,2,0,8,0]
print bucketSort(nums)
"""
[0, 0, 1, 2, 2, 3, 5, 6, 8, 65]
"""
今天想给大家推荐一本书
互粉必回! 白白