图文并茂,5分钟学习十大排序算法 —— 桶排序、基数排序

一、性能描述

桶排序
维度描述
时间复杂度- 平均:O(n + k)(k为桶数量)
- 最坏:O(n²)(所有元素集中在1个桶)
空间复杂度O(n + k)(需要额外存储桶结构)
关键影响因素- 桶的数量与数据分布的匹配度
- 桶内排序算法的选择(如插入排序 vs 归并排序)
基数排序
维度描述
时间复杂度O(d*(n + k))(d为最大位数,k为基数,如10进制中k=10)
空间复杂度O(n + k)(计数排序的额外空间)
关键影响因素- 最大位数d的大小
- 基数选择(10进制、256进制等)

二、核心差异对比

维度桶排序基数排序
排序方式按数据范围分桶,桶内独立排序按位数逐位排序(从低位到高位)
稳定性稳定(取决于桶内排序算法是否稳定)稳定(依赖底层计数排序的稳定性)
数据类型适合浮点数、整数(需均匀分布)仅适用于整数或可离散化的数据(如字符串)
空间占用桶数量多时空间开销较大空间固定(由基数和数据量决定)
预处理成本需要合理设计桶的划分策略需要计算最大位数

三、适用场景

桶排序
  1. 均匀分布数据
    数据分布均匀时,分桶后各桶元素数量均衡,效率接近线性。
    示例场景

    • 对年龄在0~100岁的人群按年龄段分组排序
    • 对0~1之间的浮点数排序(如科学计算中的采样数据)
  2. 外部排序(数据量极大)
    桶排序可将数据分到不同文件(桶),逐批加载到内存排序,适合处理超出内存的数据。
    示例场景

    • 大型日志文件按时间范围分块排序
  3. 非比较型排序需求
    当数据比较成本高时,桶排序通过分桶避免直接比较。

基数排序
  1. 固定位数整数排序
    当整数位数固定或范围可控时,基数排序效率极高。
    示例场景

    • 手机号排序(11位固定长度)
    • 身份证号排序(18位固定长度)
  2. 多关键字排序
    可逐位(或逐字段)排序,适合多维度排序需求。
    示例场景

    • 先按月份、再按日期对日期列表排序
    • 按优先级+时间戳对任务排序
  3. 稳定排序需求
    需要保持相同元素的原始顺序时,基数排序天然稳定。


四、实际代码差异示例

桶排序处理浮点数
public static void bucketSortForFloats(float[] arr) {
    int n = arr.length;
    List<Float>[] buckets = new ArrayList[n];
    
    for (int i = 0; i < n; i++) {
        buckets[i] = new ArrayList<>();
    }
    
    // 分桶(假设数据在0~1之间)
    for (float num : arr) {
        int bucketIdx = (int) (num * n);
        buckets[bucketIdx].add(num);
    }
    
    // 对每个桶排序并合并
    int idx = 0;
    for (List<Float> bucket : buckets) {
        Collections.sort(bucket);
        for (float num : bucket) {
            arr[idx++] = num;
        }
    }
}
基数排序处理字符串
public static void radixSortForStrings(String[] arr) {
    int maxLength = Arrays.stream(arr).mapToInt(String::length).max().orElse(0);
    
    for (int i = maxLength - 1; i >= 0; i--) {
        countingSortByCharacter(arr, i);
    }
}

private static void countingSortByCharacter(String[] arr, int charIdx) {
    int n = arr.length;
    String[] output = new String[n];
    int[] count = new int[256]; // ASCII范围
    
    for (String s : arr) {
        int c = (charIdx < s.length()) ? s.charAt(charIdx) : 0;
        count[c]++;
    }
    
    for (int i = 1; i < 256; i++) {
        count[i] += count[i - 1];
    }
    
    for (int i = n - 1; i >= 0; i--) {
        String s = arr[i];
        int c = (charIdx < s.length()) ? s.charAt(charIdx) : 0;
        output[count[c] - 1] = s;
        count[c]--;
    }
    
    System.arraycopy(output, 0, arr, 0, n);
}

五、总结

算法优势劣势长青场景
桶排序灵活处理浮点数、适合外部排序依赖数据分布,桶划分策略敏感均匀分布数据、大数据分块处理
基数排序高效处理固定位数整数、天然稳定仅限离散化数据、预处理成本较高手机号/身份证号排序、多关键字排序需求

选择建议

  • 若数据为整数且位数较少 → 基数排序
  • 若数据为浮点数且分布均匀 → 桶排序
  • 若需要稳定排序且数据可离散化 → 基数排序
  • 若数据量极大需分治处理 → 桶排序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值