排序-基数排序(桶排序)

基数排序(radix sort)又称桶排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。以下是基数排序的详细知识点:

一、定义与原理

  1. 基数排序又称桶排序(bucket sort),是一种分配式排序算法。它通过将所有数字分配到应在的位置,最后再覆盖到原数组完成排序的过程。
  2. 将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。
  3. 基数排序分为最高位优先法(MSD)和最低位优先法(LSD)两种。MSD从最高位开始比较,而LSD从最低位开始比较。

二、基本步骤

  1. 初始化桶:根据待排序元素的最大位数,确定需要进行的趟数。每趟排序时,创建与基数(如10进制下的10个桶)数量相等的桶。
  2. 分配元素:从最低有效位开始,遍历待排序序列,将每个元素按当前位数的值放入对应的桶中。
  3. 收集元素:按照桶的顺序,依次从每个桶中取出元素,形成新的一组序列。这一步完成了该位数上的排序。
  4. 重复以上过程:对更高位数进行相同的操作,直到处理完最高有效位。每趟排序后,待排序序列都会变得更有序。
  5. 合并结果:经过多趟排序后,待排序序列已按每一位有序,最终合并得到全局有序序列。

三、特点

  1. 基数排序是稳定的排序算法,即相等元素的相对顺序在排序后保持不变。
  2. 基数排序的时间复杂度为O(nlog(r)m),其中n为待排序元素个数,r为所采取的基数(如十进制下r=10),m为堆数(即桶的个数)。
  3. 基数排序的空间复杂度为O(n+k),其中k为待排序元素的最大位数。

四、适用场景

  1. 基数排序适用于待排序数据可以分割出独立“位”来比较的情况,如整数。
  2. 对于位数较少的正整数,基数排序通常具有较高的效率。但对于位数较多的数据,可能需要较多的内存空间来存储桶和辅助数组。

五、代码实现

基数排序的代码实现通常包括初始化桶、分配元素、收集元素和合并结果等步骤。具体的实现方式可能因编程语言和具体需求而有所不同。例如,在Java中,可以使用二维数组来表示桶,并使用循环和条件语句来实现元素的分配和收集。在Python中,可以使用列表和字典等数据结构来实现类似的功能。

以下是一个使用Java编写的基数排序(LSD,最低位优先)的示例代码。这个示例中,我们假设输入是一个非负整数数组

public class RadixSort {  
  
    // 获取一个数的最大位数  
    private static int getMaxDigit(int[] arr) {  
        int max = arr[0];  
        for (int num : arr) {  
            if (num > max) {  
                max = num;  
            }  
        }  
        int digit = 0;  
        while (max > 0) {  
            max /= 10;  
            digit++;  
        }  
        return digit;  
    }  
  
    // 基数排序  
    public static void radixSort(int[] arr) {  
        int maxDigit = getMaxDigit(arr);  
  
        // 为每一位数创建一个桶  
        int[][] bucket = new int[10][arr.length];  
        int[] count = new int[10]; // 每个桶中的元素数量  
  
        // 从最低位开始排序  
        for (int i = 1; i <= maxDigit; i++) {  
            // 将元素分配到桶中  
            for (int j = 0; j < arr.length; j++) {  
                int digit = (arr[j] / ((int) Math.pow(10, i - 1))) % 10;  
                bucket[digit][count[digit]] = arr[j];  
                count[digit]++;  
            }  
  
            // 将桶中的元素收集回数组  
            int index = 0;  
            for (int k = 0; k < 10; k++) {  
                if (count[k] == 0) continue;  
                for (int l = 0; l < count[k]; l++) {  
                    arr[index++] = bucket[k][l];  
                }  
                count[k] = 0; // 重置桶中元素数量  
            }  
        }  
    }  
  
    // 测试基数排序  
    public static void main(String[] args) {  
        int[] arr = {170, 45, 75, 90, 802, 24, 2, 66};  
        radixSort(arr);  
        for (int num : arr) {  
            System.out.print(num + " ");  
        }  
    }  
}

在这个示例中,我们首先定义了一个getMaxDigit方法来获取数组中最大数的位数,以便知道我们需要进行多少轮排序。然后,我们定义了基数排序的主体方法radixSort,它使用了一个二维数组bucket来模拟桶,并使用count数组来跟踪每个桶中的元素数量。

在排序过程中,我们从最低位开始,依次处理每一位数,将元素分配到对应的桶中,然后再从桶中收集回原数组。这个过程重复进行,直到最高位被处理完。

最后,我们在main方法中测试了基数排序,并打印了排序后的结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没出过地球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值