python计数排序_计数排序之python

话说,一口气不能吃个胖子,

一次性 学习 计数排序, 也确实容易消化不良.

下面,我们逐步学习下计数排序.

1.  已知一个简单列表 l1 = [5, 4, 3],

分析下这个列表的情况

5 > 4,  5 > 3,  所以 5 比列表中其他数大 的次数,  是  2

4 > 3,  4 < 5,   所以 4 比列表中其他数大 的次数,  是  1

3 < 4,  3 < 5,  所以 4 比列表中其他数大 的次数,  是   0

注意到了吗?

比 其他数大的次数, 序列 是    2 ->  5

1 ->  4

0 ->  3

如此,计数排序的核心原理就呼之欲出了.

统计每个数比列表其他数  大于 的次数,

次数越多  说明, 这个数越大,   反之, 大于的次数越少, 说明, 这个数就越小

下面,上代码:

1 defsort(l):2 n =len(l)3 res = [None] *n # 结果列表4 #首次循环遍历, 每个列表的数都统计

5 for i inrange(n):6 #p 表示 a[i] 大于列表其他数 的次数

7 p =08 #二次循环遍历, 列表中的每个数都和首次循环的数比较

9 for j inrange(n):10 if l[i] >l[j]:11 p += 1

12 res[p] =l[i]13 returnres14

15

16 print(sort([5, 4, 3])) 打印结果是: [3, 4, 5]

外层循环, 遍历列表每个数,

内层循环,  外层循环拿到的数 和 内层循环遍历的数, 逐个比较,  如果 外层循环 大于,  则 计数值 p + 1

内层循环结束,  则把外层循环的数, 放在 结果列表 的 索引 为 p 的位置上

2. 上面代码, 对于 列表中 , 如果数值, 都不相等, 则是ok的.

如果列表 是  [5, 5, 3]  , 打印结果 是 [3, 5, None].

为什么结果就不正确了呢?

因为 有两个 5,  计算的结果都是  p = 1

所以, 两个 5 , 都被放在结果列表  索引 1 的位置上了,

索引 2 的位置,没有放数.

优化后的代码逻辑如下:

1 defsort(l):2 n =len(l)3 res = [None] *n4 #首次循环遍历, 每个列表的数都统计

5 for i inrange(n):6 #p 表示 a[i] 大于列表其他数 的次数

7 p =08 #q 表示 等于 a[i] 的次数

9 q =010 #二次循环遍历, 列表中的每个数都和首次循环的数比较

11 for j inrange(n):12 if l[i] >l[j]:13 p += 1

14 elif l[i] ==l[j]:15 q += 1

16 for k in range(p, p+q): # q表示 相等的次数,就表示, 从 P 开始索引后, 连续 q 次,都是同样的 数17 res[k] =l[i]18 returnres19

20

21 print(sort([5, 5, 3])) 打印结果是: [3, 5, 5]

上述改进代码,容易困惑的地方: 是 16 - 17 行代码,

print(k, p, q, p+q)

建议读者, 在 16 和 17 之间, 加入 如上代码, 打印看看

16, 17行代码, 逻辑上也不完美,

比如, 两个 5, 就会被 重复赋值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值