宝藏速成秘籍(8)基数排序法

一、前言

1.1、概念

       基数排序法是一种非比较性的排序算法,通过将待排序的元素分割成独立的位数,然后按照每个位数的值进行排序。它可以用于对整数或字符串等数据类型进行排序。

1.2、排序步骤 

  1. 确定待排序元素的位数,并根据最大位数创建对应数量的桶。

  2. 从最低位开始,按照每个位数的值将待排序的元素分配到对应的桶中。可以使用取模运算或者除法运算来获取每个位数的值。

  3. 按照桶的顺序,依次将桶中的元素取出,形成新的待排序序列。

  4. 重复上述步骤2和步骤3,直到按照最高位的值排序完成。

  5. 最终得到的序列即为有序的结果。

二、方法分析  

       基数排序法是一种稳定的排序算法,适用于对非负整数进行排序。基数排序法的核心思想是通过将待排序元素按照位数的值进行分配和收集,从而实现排序。

三、举例说明 

我们以LSD基数排序为例,对一个数组 {170, 45, 75, 90, 802, 24, 2, 66} 进行排序。

1. 从个位开始,对数组进行排序。
2. 然后对十位进行排序。
3. 最后对百位进行排序。

初始数组: {170, 45, 75, 90, 802, 24, 2, 66}

按个位排序:
- 分桶: {170, 90}, {802, 2}, {24, 75}, {45}, {66}
- 排序后: {170, 90, 802, 2, 24, 75, 45, 66}

按十位排序:
- 分桶: {802, 2}, {24, 45}, {66}, {170, 75}, {90}
- 排序后: {802, 2, 24, 45, 66, 170, 75, 90}

按百位排序:
- 分桶: {2, 24, 45, 66, 75, 90}, {170}, {802}
- 排序后: {2, 24, 45, 66, 75, 90, 170, 802}

最终排序结果为: {2, 24, 45, 66, 75, 90, 170, 802}

四、编码实现   

import java.util.Arrays;

public class RadixSort {
    public static void main(String[] args) {
        int[] arr = {170, 45, 75, 90, 802, 24, 2, 66};
        radixSort(arr);
        System.out.println("排序后的数组:");
        System.out.println(Arrays.toString(arr));
    }

    public static void radixSort(int[] arr) {
        // 找到最大数以确定最大的位数
        int max = Arrays.stream(arr).max().getAsInt();
        
        // 从个位开始,对每一位进行计数排序
        for (int exp = 1; max / exp > 0; exp *= 10) {
            countingSort(arr, exp);
        }
    }

    public static void countingSort(int[] arr, int exp) {
        int n = arr.length;
        int[] output = new int[n]; // 输出数组
        int[] count = new int[10]; // 计数数组

        // 初始化计数数组
        Arrays.fill(count, 0);

        // 计数出现的次数
        for (int i = 0; i < n; i++) {
            int index = (arr[i] / exp) % 10;
            count[index]++;
        }

        // 计算位置索引
        for (int i = 1; i < 10; i++) {
            count[i] += count[i - 1];
        }

        // 构建输出数组
        for (int i = n - 1; i >= 0; i--) {
            int index = (arr[i] / exp) % 10;
            output[count[index] - 1] = arr[i];
            count[index]--;
        }

        // 将输出数组复制到arr
        System.arraycopy(output, 0, arr, 0, n);
    }
}

 运行结果:

 五、方法评价 

### 时间复杂度

基数排序的时间复杂度是O(d * (n + k)),其中:
- `n` 是待排序元素的个数。
- `d` 是数字的最大位数。
- `k` 是计数排序的桶数(通常为10,对于十进制数字)。

### 空间复杂度

基数排序的空间复杂度为O(n + k),因为需要额外的空间来存储计数数组和输出数组。在处理大规模数据时,这些额外的空间开销可能会成为一个问题。

### 稳定性

基数排序是一种稳定排序算法,即相同键值的元素在排序后保持相对顺序。这是因为每一轮排序都是基于稳定的计数排序实现的。

### 适用性

基数排序适用于以下情况:
1.定长整数排序:当所有整数的位数相同或长度差不多时,基数排序非常高效。
2.字符串排序:当字符串长度相同时,也可以使用基数排序按字典顺序排序。
3.非负整数排序:基数排序通常用于非负整数的排序,因为负数处理起来会比较复杂。

### 优点

1.高效性:在特定条件下,基数排序的效率高于比较型排序算法,如快速排序和归并排序。
2.稳定性:由于基数排序是稳定的,因此它可以很好地保持相同键值元素的相对顺序。

### 缺点

1.空间消耗:基数排序需要额外的存储空间,这在内存有限的情况下可能是一个缺点。
2.适用范围有限:基数排序主要适用于整数和字符串排序,对于浮点数或其他复杂数据类型,适用性较差。
3.依赖数据特性:基数排序的效率依赖于数据的位数,对于位数较大的数据,效率可能不如其他排序算法。

 结语 

 如果你想拥有你从未拥有过的东西,那么你就得去做你从未做过的事情

!!!

  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值