2
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 行。可能是因为我是 python 新手或者只是愚蠢。

  1. 第一种情况发生了什么?当范围是 [ ] ?...“对于空数组范围内的每个 c ....?
  2. 我也没有array[i] = a上线。如果 a 是计数数组中可能为零的第一个元素,那么如何添加它......?真的很迷茫...

干杯!

4

3 回答 3

1

你显然已经知道那count[a]将是 0,range(count[a])因此那将是[].

所以,你要问的是,这是做什么的:

for i in []:
   do_stuff(i)

答案是它循环遍历每个 0 元素——换句话说,它根本不循环。它什么也不做。 *

这在声明的文档中进行for解释:

... 然后,该套件对迭代器提供的每个项目执行一次......当项目用尽时(即当序列为空时立即......) ......循环终止。


这隐含地解释了你的第二个困惑:

如果 a 是计数数组中可能为零的第一个元素,如何添加它

count[a]为 0 时,您将永远不会进入循环,因此这种情况永远不会出现。


* 如果for语句有else子句,它会运行else子句。

于 2013-11-08T01:37:17.007 回答
0

我简化了你的部分代码,也许它可以帮助你更好地理解算法的核心。在计算完数组中的所有元素后,我们可以仅使用存储在count[].

array=[]
for a in range(m): 
    array.extend([a]*count[a])
于 2013-11-08T01:47:26.023 回答
0
  1. range将为您提供具有指定开始和结束值的列表。例如

    print range(5) 
    

    将打印

    [0, 1, 2, 3, 4]
    

    当你说,range(m)或者range(count[a])它会生成一个列表,直到mcount[a]从 0 开始。

  2. 关于array[i] = a

    在 中range(m),对于每个元素,代码检查count[a]. 如果count[a]为 0,则不会执行第二个循环。(range(0)将产生一个空列表)所以,for when ais 0 array[i] = a不会被执行。

于 2013-11-08T01:35:10.193 回答