计数排序

要理解计数排序,就必须要了解什么是计数,以及为什么只适用于整数。

可以将排序问题拆分为一下两个子问题:

(1)如何确定原始数组内元素的排位次序并建立排序数组与其对应?

即101→1,103→5....

① 原始数组内元素是不连续的,那如何将不连续的元素与排序数组一一对应呢。这里通过 元素值-最小元素值=计数数组下标 的方法确定计数数组,计数数组下标为【0,max-len+1】。统计次数作为其元素值,不存在的元素值默认为0。

原始数组

计数数组

② 如图所示,计数数组的下标从原始数组的最小值开始算起,0=101-101,1表示101出现1次;2=103-101,1表示103出现3次。

如何根据出现次数确定排位次序呢?可以看到,计数数组的下标在创建之时便从小到大与原始数组对应,因此只要将出现的次数累加便可以得到按值大小比较的排位次序。

排序数组

 (2)如何根据排序数组的位序重新排列原始数组内元素?

遵循两个原则即可

原则一:排序数组次序-1即为其在新数组的下标

例如,原始数组元素值101所对应的排序数组下标(101-101=0)处的位序值为1,表明其是第一小的元素值。1-1=0,就在新数组的下标0处赋值101。

原则二:为了处理数值相同位序相同的情况,在排列完一个元素值后需要把排序数组中其对应的位序-1

例如,原始数组103存在3个值,对应的排序数组下标(103-101=2)处的位序值为5。排列时对遇到的第一个103按照之前的方法,在新数组下标4处赋值103;而当遇到第二个103时,如果还是在下标4处赋值则会重复。直观来看,之所以位序值为5是因为数值相同而并列排序(1,2,5,5,5)。因此在对第一个103排列完成后可将位序值减一,下次排列时新数组的下标就变为(5-1-1=3),在下标3处赋值即可解决这一问题,保证不遗漏原始数组中的相同元素。

def countingSort(arr):
    min_value = min(arr)
    max_value = max(arr)
    count = [0] * (max_value - min_value + 1)  # 下标与范围内所有元素
    for i in arr:
        count[i - min_value] += 1  # 范围内所有元素出现的次数
    for i in range(1, len(count)):
        count[i] += count[i - 1]  # 范围内所有元素的位序
    result = [0] * len(arr)  # 依照位序将原数组的元素重新排列
    for i in arr:
        result[count[i - min_value] - 1] = i
        count[i - min_value] -= 1
    return result

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值