计数排序的python实现

无论是归并排序、堆排序或是快速排序,它们都是通过元素之间的比较进行排序,所以在这些排序方法的执行过程中,数组自身的性质(数组中各元素的排列顺序)会直接影响到时间或者内存成本的大小。这类排序算法称为比较排序,这些排序算法的下界都是 n l g n nlgn nlgn
计数排序不是比较排序,它的执行效果不依赖于愿数组本身元素的排列。
计数排序的思想是假设大小为 n n n的数组中的所有元素都是在区间 [ 0 , k ) [0,k) [0,k)上的整数,这样对于每一个元素 x x x,只要确定数组中小于 x x x的元素个数,我们就可以将 x x x放到正确的排序位置上。例如确定了有10个元素小于 x x x,这样的话,当输出结果序列时(从小到大排列的数组),我们就可以确定 x x x一定是在结果序列的第十一个位置。当然,如果有元素的值相同的话,符号上的细节处要略作修改,不能出现多个相同的值出现在同一个位置上。
对于一个有 n n n个元素的数组 l i s t 0 list0 list0,对其进行计数排序时,需要一个对其元素数目进行记录的数组 l i s t 1 list1 list1以及一个相同大小的输出数组 l i s t 2 list2 list2
具体的python实现如下。

#待排序数组为l0,数组元素值域为[0,k)
def counting_sort(l0,k):
   #初始化结果数组l2,记录数组l1
    l1=[0]*k
    l2=[-1]*len(l0)
    #遍历原数组,使用l1记录所有元素的个数,将元素值为t的个数记录在l1[t]中
    for i in range(len(l0)):
        l1[l0[i]]=l1[l0[i]]+1
    #累加得到原数组中小于t的元素个数
    for j in range(1,k,1):
        l1[j]=l1[j]+l1[j-1]
    #根据l1中得到的数据(小于t的元素个数)将每个元素放到结果数组l2中正确的位置上
    for i in range(len(l0)-1,-1,-1):
        #从原数组的最后向前循环可以保证:具有相同值的元素在输出数组中的相对位置与在元素组中一样
        l2[l1[l0[i]]-1]=l0[i]
        #个数减一,下一个相同的元素往前排
        l1[l0[i]]=l1[l0[i]]-1
    return l2

我借用《算法导论》里的例子来解释这个程序的运行。对于要排序的数组 l 0 = [ 2 , 5 , 3 , 0 , 2 , 3 , 0 , 3 ] l0=[2,5,3,0,2,3,0,3] l0=[2,5,3,0,2,3,0,3],我们还需要知道的一个值就是所有元素的值域 [ 0 , k ) [0,k) [0,k),显然这里 k = 6 k=6 k=6
下面来展示下函数运行过程中,变量 l 1 l1 l1 l 2 l2 l2变化情况。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
对于数组 l 0 l0 l0,当 k = Θ ( n ) k=Θ(n) k=Θ(n)时,排序的运行时间为 Θ ( n ) Θ(n) Θ(n)。是一个很优秀的算法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值