图解排序 8/10 - 桶排序
Posted 超越技术
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图解排序 8/10 - 桶排序相关的知识,希望对你有一定的参考价值。
上一篇计数排序也是一种桶排序。桶排序的核心思想是把数据分到若干个“桶”中,对“桶”中的元素进行排序,最终把“桶”中已排序好的数据合并为一个有序序列。
桶排序
以 arr = [ 8, 1, 4, 6, 2, 3, 5, 7 ] 为例,排序前需要确定桶的个数,和确定桶中元素的取值范围:
代码
+ (NSArray *)bucketSort:(NSArray *)datas {
// 1.找出数组中最大数和最小数
NSNumber *max = [datas firstObject];
NSNumber *min = [datas firstObject];
for (int i = 0; i < datas.count; i++) {
NSNumber *item = datas[i];
if ([item integerValue] > [max integerValue]) {
max = item;
}
if ([item integerValue] < [min integerValue]) {
min = item;
}
}
// 2.创建桶,桶的个数为 3
int maxBucket = 3;
NSMutableArray *buckets = [NSMutableArray arrayWithCapacity:maxBucket];
for (int i = 0; i < maxBucket; i++) {
NSMutableArray *aBucket = [NSMutableArray array];
[buckets addObject:aBucket];
}
// 3.把数据分配到桶中,桶中的数据是有序的
// a.计算桶中数据的平均值,这样分组数据的时候会把数据放到对应的桶中
float space = ([max integerValue] - [min integerValue] + 1) / (maxBucket*1.0);
for (int i = 0; i < datas.count; i++) {
// b.根据数据值计算它在桶中的位置
int index = floor(([datas[i] integerValue] - [min integerValue]) / space);
NSMutableArray *bucket = buckets[index];
int maxCount = (int)bucket.count;
NSInteger minIndex = 0;
for (int j = maxCount - 1; j >= 0; j--) {
if ([datas[i] integerValue] > [bucket[j] integerValue]) {
minIndex = j+1;
break;
}
}
[bucket insertObject:datas[i] atIndex:minIndex];
}
// 4.把桶中的数据重新组装起来
NSMutableArray *results = [NSMutableArray array];
[buckets enumerateObjectsUsingBlock:^(NSArray *obj, NSUInteger idx, BOOL * _Nonnull stop) {
[results addObjectsFromArray:obj];
}];
return results;
}
特点
稳定性:在元素拆分的时候,相同元素会被分到同一组中,合并的时候也是按顺序合并,故稳定。
空间复杂度:桶的个数加元素的个数,为 O ( n + k );
时间复杂度:最好为 O( n + k ),最坏为 O(n * n);
感想
计数排序和桶排序的思想都是把数据进行拆分,然后把数据放到不同的桶中,对桶中的元素进行排序,最终合并桶。
推荐阅读:
图解算法
以上是关于图解排序 8/10 - 桶排序的主要内容,如果未能解决你的问题,请参考以下文章
十大排序总结(js实现稳定性内外部排序区别时间空间复杂度冒泡快速直接选择堆直接插入希尔桶基数归并计数排序)