def counting_sort(array, maxval):
"""in-place counting sort"""
m = maxval + 1
count = [0] * m # init with zeros
for a in array:
count[a] += 1 # count occurences
i = 0
for a in range(m): # emit
for c in range(count[a]): # - emit 'count[a]' copies of 'a' #CONFUSED
array[i] = a
i += 1
return array
print counting_sort( [1, 4, 7, 2, 1, 3, 2, 1, 4, 2, 3, 2, 1], 7 )
# prints: [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 7]
所以在上面的代码中,我不明白我标记为混乱的行,最后一行前4行。 可能是因为我是蟒蛇新手或者只是愚蠢。
array[i] = a
。如果a是计数数组中第一个可能为零的元素,那怎么可以添加....?真的很困惑...... 干杯!
答案 0 :(得分:1)
您显然已经发现count[a]
将为0,因此range(count[a])
将为[]
。
所以,你问的是,这是做什么的:
for i in []:
do_stuff(i)
答案是它循环遍历每个0元素 - 换句话说,它根本不循环。它什么也没做。*
the for
statement的文档中解释了这一点:
...然后对迭代器提供的每个项执行一次套件... 当项目耗尽时(当序列为空时......) ......循环终止。
这隐含地解释了你的第二点困惑:
如果a是计数数组中可能为零的第一个元素,那么如何添加
当count[a]
为0时,您将永远不会进入循环,因此不会出现这种情况。
*如果for
语句具有else
子句,则它会运行else
子句。
答案 1 :(得分:0)
range
会为您提供包含指定开始值和结束值的列表。例如
print range(5)
将打印
[0, 1, 2, 3, 4]
当您说range(m)
或range(count[a])
时,它会从{0}开始生成一个列表,直到m
或count[a]
。
关于array[i] = a
在range(m)
中,代码检查count[a]
。如果count[a]
为0,则不执行第二个循环。 (range(0)
将生成一个空列表)因此,当a
为0时array[i] = a
将不会被执行。
答案 2 :(得分:0)
我简化了部分代码,也许它可以帮助您很好地理解算法的核心。在计算了数组中的所有元素之后,我们只能使用count[]
中存储的信息重建排序数组。
array=[]
for a in range(m):
array.extend([a]*count[a])