如何使用队列进行Radix排序?

时间:2013-03-21 04:02:22

标签: python algorithm sorting loops radix

如何使用队列正确地对列表进行排序?

我正在使用Python 3x。

这是我尝试将队列用作垃圾箱,因为队列是先进先出的数据结构。

from my_queue import Queue
def rsort(n):
    '''(list of int) -> list of int
    '''
    list_length = len(n)
    val = 0
    mod = 10
    k = 1
    bin_list = []
    alist = n
    for bins in range(0,10):
        bin_list.append(Queue())

    while val == 0:
        for num in alist:
            sig_dig = num % mod
            sig_dig = int(sig_dig / k)
            bin_list[sig_dig].enqueue(num)

        if bin_list[0].size() == list_length:
            alist.append(bin_list[0].dequeue())

        else:
            mod = mod * 10
            k = k * 10            

        new_list = []
        for bins in bin_list:
            if not bins.is_empty():
                new_list.append(bins.dequeue())
            alist = new_list

        return alist

我的代码可以很好地处理小数字,例如:[3,2,6,5,8,7]

但是当列表中的值变大时,如:[240, 28, 5, 18, 140, 2]

我的程序不再对列表进行排序,数字最终丢失并且无序。

我一直在玩我的程序,但我无法解决它:(

1 个答案:

答案 0 :(得分:1)

您的代码中有一些似乎有问题的东西。我不确定究竟是哪一个导致了你所看到的问题,但可能所有这些都需要修复才能得到正确的结果。

首先,快速说明:只需使用一个整数就可以在每个数字中找到正确的数字,从而简化逻辑。我建议一个值从零开始并上升到某个值(你想要排序的位数)。您可以使用sig_dig = num // 10**k % 10找到给定列表项的数字值。 //运算符强制Python使用“floor division”,截断正常除法的非整数部分。

无论如何,第一个问题是你在val == 0上循环,但你永远不会修改val,并且在循环结束前返回一个值(所以你永远不会这样做反正不止一次)。您可以通过使用max_digits = int(math.ceil(math.log(max(lst), 10)))之类的内容计算列表中最长值的位数来解决此问题。然后,您可以使循环更简单:for k in range(max_digits):

我看到的下一个问题是你可能没有正确地将垃圾箱中的值恢复到列表中。你只需要调用dequeue一次,但你应该反复调用它,直到队列为空。或者,如果我误解了您正在使用的Queue API并且dequeue返回了所有队列的值,则需要使用extend将它们全部添加到列表中。< / p>

这是我认为你想拥有的东西,最后:

import math

from my_queue import Queue

def rsort(n):
    '''(list of int) -> list of int
    '''
    bin_list = [Queue for _ in range(10)]
    max_digits = int(math.ceil(math.log(max(lst), 10))) # calculate # of digits

    for k in range(max_digits):
        for num in alist:
            sig_dig = num / 10**k % 10 # find digit's value
            bin_list[sig_dig].enqueue(num)

        n = [] # we can reuse the name `n`, rather than using a different name
        for bins in bin_list:
            while not bins.is_empty(): # loop to dequeue all values
                n.append(bins.dequeue())

    return n # the return statement is outside the loop!