python开发之算法&数据结构(三)

本文介绍了基于桶排序思想的三种排序算法:计数排序、基数排序和桶排序。计数排序通过下标记录元素出现次数实现排序,基数排序利用位数分配到桶中,桶排序将元素分配到值域的桶内。文章详细阐述了每种排序的过程、优化、代码实现、时间复杂度和空间复杂度。
摘要由CSDN通过智能技术生成

一、基于桶排序思想

1. 计数排序

计数排序是一个非基于比较的排序算法,他的思想是用下标记录每个元素出现的次数,而下标涵盖了所有元素的范围,最后按照下标顺序,次数是多少就输出多少次下标,输出的即为排序后的结果。

1.1 排序过程

在这里插入图片描述

# 计数排序:
def count_sort(li,max_count=100):
    count = [0 for _ in range(max_count+1)]
    for i in li:
        count[i] += 1
    li.clear()
    for index,val in enumerate(count):
        for i in range(val):
            li.append(index)

注: 该方法存在一个问:无法保证相同元素之间的相对位置。比如上图数字代表年级,同为3年级的有两个班:3年级文科班和3年级理科班,假如排序前文科班排在理科班前面,按上述方法排序完成后无法保证文科班还在理科班前面,因为两个3都无法表示自己是哪个班的。

1.2 排序优化

在上述方法的基础上,计数器 每个下标对应的数都是前面所有数的和 (计数器下标从1开始),如果计数器下标从0开始,就把下标对应的每个数都减1。接着从要排序的数列的 最后 一个元素开始,在计数器中找对应的下标,例如元素3就找计数器下标3,发现其对应的值为5,则该元素3在排好序的新序列中的位置是下标5的位置,并且计数器下标3对应的数减1;以此类推直到所有元素都放入新列表中,期间一直要保持计数器的更新。

  • 采用该方法排序后的结果可以保证相同元素的相对位置不变,也就是说优化计数排序算法是 稳定 的。
  • 对于把计数器每个下标对应的数都加上前面所有数,可以理解为小于等于2的元素占据着新列表下标从0到3的位置(如下图);小于等于4的元素占据着新列表下标从0到7的位置。
  • 原列表最后一个3,排序完就在新列表下标为5的位置,然后计数器5位置的值-1变为4,原列表倒数第二个3,排序完就在新列表下标为4的位置。
  • 还有一种情况是元素范围从 非0或非1 开始,比如20-26,那就把新列表建为(26-20+1)的长度。

在这里插入图片描述

1.3 代码实现

计数排序代码关键点:计数器、计数器与新列表的对应关系

代码思路:首先得到原列表最大最小值,确定计数器范围;然后遍历原列表,在计数器中记录每个元素出现的次数;再循环将计数器中每个下标对应的数都加上前面所有数,如果计数器下标从0开始,则还需要把计数器中的每个值都 -1;最后对原列表倒序取值,放到新列表的对应位置。

# 计数排序优化:
def CountingSort(li):
    maxNum=max(li)  # 获取li中的最大值和最小值
    minNum=min(li)
    # 以最大值和最小值的差作为计数器的长度,并构建计数器,初始化为0
    length=maxNum-minNum+1
    countLi=[0 for _ in range(length)]
    resultLi
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值