基数排序 LSD py

链接:https://www.nowcoder.com/questionTerminal/1e68ccb2cbc74c3d9e0dea0c568789b8
设数组S[]={154,265,146,31,213,14,157,189,91,10,111,123},采用最低位优先(LSD)基数排序将S排列成升序序列,第1趟分配收集后元素14之前,之后紧邻的元素是()
第1趟分配收集后的结果为:10,31,91,111,213,123,154,14,265,146,157,189

基数排序可以排序整数、字符。原理是补齐长度,按位比较,按照比较方向可以分为低位优先(Least Significant Digit first, LSD)和高位优先 (MSD)。

平均时间复杂度:O(n*k),k是最大位数

原理

这里以比较整形数字为例:

  1. 确定最大数的位数:首先找出待排序数中的最大数,以确定最大位数。
  2. 初始化桶:创建10个桶(0-9),每个桶用于存放对应位数的数字。
  3. 分配数字到桶:从 最低位/最高位 开始,遍历每个数字,根据当前位的数值将其放入相应的桶中。
  4. 收集桶中数字:按顺序收集桶中的数字,放回原数组。
  5. 重复过程:对每一位重复上述分配和收集过程,直到 最高位/最低位。

低位优先

def radix_sort(arr):
    # 找出最大数以确定最大位数
    max_num = max(arr)
    # 计算最大数的位数
    max_digits = len(str(max_num))

    # 初始化桶
    buckets = [[] for _ in range(10)]

    # 从最低位开始,对每一位进行排序
    for digit in range(max_digits):
        # 分配数字到桶
        for num in arr:
            # 计算当前位的数值
            current_digit = (num // (10 ** digit)) % 10
            # 将数字放入相应的桶中,相同数字放在同一个桶,列表可以保证顺序
            buckets[current_digit].append(num)

        # 收集桶中的数字,放回原数组
        # arr = [num for bucket in buckets for num in bucket] #  不好理解
        arr.clear()
        for bucket in buckets:
            arr.extend(bucket)

        # 清空桶,为下一次分配做准备
        buckets = [[] for _ in range(10)]
        print(f"DEBUG digit: {digit}, arr: {arr}")

    return arr

# 测试数组
arr = [154, 265, 146, 31, 213, 14, 157, 189, 91, 10, 111, 123]
# 执行基数排序
sorted_arr = radix_sort(arr)
# 打印排序后的数组
print(sorted_arr)
DEBUG digit: 0, arr: [10, 31, 91, 111, 213, 123, 154, 14, 265, 146, 157, 189]
DEBUG digit: 1, arr: [10, 111, 213, 14, 123, 31, 146, 154, 157, 265, 189, 91]
DEBUG digit: 2, arr: [10, 14, 31, 91, 111, 123, 146, 154, 157, 189, 213, 265]
[10, 14, 31, 91, 111, 123, 146, 154, 157, 189, 213, 265]

refer

图文总结」程序员必知必会的十大排序算法 bigsai 发起于 2020-11-28

posted @ 2024-04-27 12:37  沙滩炒花蛤  阅读(248)  评论(0编辑  收藏  举报