Python学习算法系列(6):基数排序与计数排序

部署运行你感兴趣的模型镜像

Python学习算法系列(6):基数排序与计数排序

1. 引言

在前几篇博客中,我们已经学习了常见的比较排序算法,如归并排序堆排序。本篇博客将介绍另外两种非比较型排序算法:

  • 基数排序(Radix Sort)
  • 计数排序(Counting Sort)

这两种算法的时间复杂度通常优于传统的比较排序算法,尤其适用于对整数或有限范围的数字进行排序。


2. 计数排序(Counting Sort)

2.1 计数排序原理

计数排序是一种非比较排序算法,它的基本思想是:

  1. 统计数组中每个元素出现的次数。
  2. 根据统计结果,直接确定每个元素的最终位置。

计数排序的关键在于计数数组,其大小由输入数据的最大值决定。

2.2 计数排序代码实现

def counting_sort(arr):
    # 1. 找到数组中的最大值
    max_val = max(arr)
    # 2. 创建计数数组
    count = [0] * (max_val + 1)
    
    # 3. 统计每个元素出现的次数
    for num in arr:
        count[num] += 1
    
    # 4. 根据计数数组重新构建排序后的数组
    sorted_arr = []
    for i in range(len(count)):
        sorted_arr.extend([i] * count[i])  # 将元素按其出现次数添加到排序数组
    
    return sorted_arr

# 测试计数排序
arr = [4, 2, 2, 8, 3, 3, 1]
sorted_arr = counting_sort(arr)
print("排序后的数组:", sorted_arr)  # 输出 [1, 2, 2, 3, 3, 4, 8]

2.3 计数排序时间复杂度

计数排序的时间复杂度为:

  • 最好情况:O(n + k)
  • 最坏情况:O(n + k)
  • 平均情况:O(n + k)

其中,n 为输入数组的大小,k 为数据范围(最大值与最小值之差)。

计数排序的空间复杂度为 O(k),因为需要额外的空间来存储计数数组。


3. 基数排序(Radix Sort)

3.1 基数排序原理

基数排序是一种基于数字的排序算法,它的基本思想是:

  1. 将每个元素按位数(从低位到高位)进行排序,使用稳定的排序算法(如计数排序)进行每次排序。
  2. 从最低位开始逐位排序,直到所有位都排序完毕。

基数排序适用于排序整数或字符串,它的时间复杂度与数字的位数有关,而不是与数据的大小直接相关。

3.2 基数排序代码实现

def counting_sort_for_radix(arr, exp):
    n = len(arr)
    output = [0] * n
    count = [0] * 10
    
    # 统计当前位的数字出现的次数
    for i in range(n):
        index = arr[i] // exp
        count[index % 10] += 1
    
    # 计算计数数组的累计和
    for i in range(1, 10):
        count[i] += count[i - 1]
    
    # 构建输出数组
    i = n - 1
    while i >= 0:
        index = arr[i] // exp
        output[count[index % 10] - 1] = arr[i]
        count[index % 10] -= 1
        i -= 1
    
    # 将排序后的结果复制回原数组
    for i in range(n):
        arr[i] = output[i]

def radix_sort(arr):
    # 找到最大数,用于确定排序的次数
    max_val = max(arr)
    
    # 对每一位数字进行排序
    exp = 1
    while max_val // exp > 0:
        counting_sort_for_radix(arr, exp)
        exp *= 10

# 测试基数排序
arr = [170, 45, 75, 90, 802, 24, 2, 66]
radix_sort(arr)
print("排序后的数组:", arr)  # 输出 [2, 24, 45, 66, 75, 90, 170, 802]

3.3 基数排序时间复杂度

基数排序的时间复杂度为:

  • 最好情况:O(nk)
  • 最坏情况:O(nk)
  • 平均情况:O(nk)

其中,n 为输入数组的大小,k 为数字的位数。

基数排序的空间复杂度为 O(n + k),其中 n 为数组的大小,k 为数字的范围。


4. 排序算法的性能比较

以下是 计数排序基数排序 与其他常见排序算法的时间复杂度比较:

算法时间复杂度(最好情况)时间复杂度(最坏情况)空间复杂度
冒泡排序O(n)O(n^2)O(1)
选择排序O(n^2)O(n^2)O(1)
插入排序O(n)O(n^2)O(1)
快速排序O(n log n)O(n^2)O(log n)
归并排序O(n log n)O(n log n)O(n)
堆排序O(n log n)O(n log n)O(1)
计数排序O(n + k)O(n + k)O(k)
基数排序O(nk)O(nk)O(n + k)

5. 总结

  • 计数排序:适用于数据范围较小的情况,时间复杂度为 O(n + k),但空间复杂度较高。
  • 基数排序:适用于大数据量的整数排序,时间复杂度为 O(nk),但它需要额外的空间来存储中间结果。
  • 排序算法优化:对于不同的输入数据,选择合适的排序算法能够显著提高效率。

📢 下一篇 Python学习算法系列(7):动态规划与贪心算法,敬请期待!🚀

💡 如果你喜欢这篇文章,欢迎点赞、收藏,并关注本系列!

您可能感兴趣的与本文相关的镜像

Python3.11

Python3.11

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值