基数排序

  • 基数排序通过对数据不同位的数字大小进行分装再实现排序,是一种非比较排序,其实现分为MSD和LSD两种方式,其中LSD部分代码包含计数排序(点击查看计数排序)的思想。

代码

LSD实现:

def lsd_radix(arr):
    Max = max(arr)
    exponent = 1

    while Max // exponent > 0:
        count_sort(arr, exponent)
        exponent *= 10

    return arr


def count_sort(arr, exponent):
    count = [0] * 10
    temporary = [0]*len(arr) # 这里要搞清计数列表(count)和赋值列表(temporary)区别,大小不同

    for i in arr:
        index = i // exponent
        count[index % 10] += 1

    for i in range(1, 10):
        count[i] += count[i - 1]

    for i in reversed(arr): # 注意逆序
        index = i // exponent
        temporary[count[index % 10] - 1] = i
        count[index % 10] -= 1

    # 使用for循环更加简洁
    n = len(arr)-1
    while n >= 0:
        arr[n] = temporary[n]
        n -= 1

输入:

  • [170, 45, 75, 90, 802, 24, 2, 66, 66]

输出:

  • [2, 24, 45, 66, 66, 75, 90, 170, 802]

MSD实现:

def msd_radix(arr):
    def msd(arr,exponent):
        if len(arr) <= 1 or exponent == 0:
            return arr

        count = [[] for _ in range(10)] # 分桶
        temporary = []

        for i in arr:
            index = i // exponent
            count[index % 10].append(i) # 注意此处,避免写错
    
        for i in count:
            if i:
                temporary.extend(msd(i,exponent//10)) # '//'用来确保列表索引为整数
        return temporary


    Max = max(arr)
    exponent = 1
    while Max // exponent > 10:
        exponent *= 10

    return msd(arr,exponent)


输入:

  • [170, 45, 75, 90, 802, 24, 2, 66, 66]

输出:

  • [2, 24, 45, 66, 66, 75, 90, 170, 802]

MSD(Most Significant Digit)和 LSD(Least Significant Digit)基数排序是两种基数排序方法,它们在处理数据时有一些关键的区别:

1. 排序方法

  • MSD(Most Significant Digit)基数排序

    • 排序方式:从最高位(最重要的位)开始排序,然后逐步处理到低位(次重要的位)。
    • 递归特性:通常采用递归方式处理每一位。
    • 应用场景:适合处理具有较多位数的数据,特别是在位数较多时更为高效。
  • LSD(Least Significant Digit)基数排序

    • 排序方式:从最低位(最不重要的位)开始排序,然后逐步处理到高位(最重要的位)。
    • 迭代特性:通常采用迭代方式处理每一位。
    • 应用场景:适合处理数据位数较少的情况,简单且易于实现。

2. 处理顺序

  • MSD

    • 处理数据时先处理最高位,逐步递归处理到最低位。例如,对于整数 345 和 789,MSD 会先按百位(3 和 7)排序,然后处理十位和个位。
  • LSD

    • 处理数据时从最低位开始,例如对于整数 345 和 789,LSD 会先按个位(5 和 9)排序,然后处理十位和百位。

3. 时间复杂度

  • MSD

    • 在处理每一位时,复杂度主要取决于位数和每个桶内的排序。总体时间复杂度为 O(n⋅k),其中 n 是元素个数,k是最大位数。
    • MSD 的递归深度取决于位数,因此在处理大数据时可能会有更高的内存开销。
  • LSD

    • 对每一位进行排序,通常时间复杂度为 O(n⋅k)。LSD 方法不涉及递归,相对内存开销较小。

4. 内存使用

  • MSD

    • 由于递归调用和桶的使用,MSD 可能需要更多的内存来存储中间结果。
  • LSD

    • 由于使用迭代方法,LSD 通常需要较少的内存,适合内存有限的环境。

5. 实现复杂性

  • MSD

    • 实现上可能会更复杂,需要处理递归和多级桶排序。
  • LSD

    • 实现上通常较为简单,因为它只是逐位进行排序,不涉及递归。

总结

  • MSD 基数排序 从最高位开始处理,通常适合位数较多的数据。
  • LSD 基数排序 从最低位开始处理,通常适合位数较少的数据,实施较简单。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值