我的基数排序有什么问题?

时间:2014-04-03 17:21:44

标签: python sorting python-3.x radix-sort

注意:我使用的是python 3。

我正在尝试按字母顺序对单词列表进行排序。

这是我的排序:

def radix_sort(List, length):
    buckets = [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
    for i in range (length-1, -1, -1):    #for every letter "column"
        for word in List:    #for every word 
            index = ord(word.azWord[i])-ord('a')   #get the index of the word
            buckets[index].append(word)     #add word object to correct bucket
    List[:] = []
    for containedList in buckets:
        List.extend(containedList)

它正在这个循环中使用:

for x in range(0,maxL):
    radix_sort(results[x], x)

maxL是我拥有的最长单词的长度,因此从0到maxL的迭代将遍历整个列表。

我的列表结果[]是一个列表列表。结果中的每个列表都包含一个如下所述的单词对象:

class word(object): #object class

    def __init__(self, originalWord=None, azWord=None, wLength=None):
        self.originalWord = originalWord
        self.azWord = azWord
        self.wLength = wLength

例如,结果[3]应该包含wLength为3的所有单词的列表。

当我为整个程序提供以下输入时:

hello
world
alphabetical
dog
cat
potato
stack

使用这段代码:

for row in results:
    for item in row:
        print(item.originalWord)

打印:

cat
cat
dog
dog
dog
cat
stack
stack
world
hello
hello
stack
hello
hello
world
hello
world
world
stack
stack
world
potato
potato
potato
potato
potato
potato
alphabetical

我非常确定我在打印时正确地遍历结果[]。为什么我的radix_sort没有给我正确的结果?我尝试使用调试器,但没有运气。

编辑:我将代码更改为:

def radix_sort(List, length):
    for i in range (length-1, -1, -1): 
        for word in List:  
            buckets = [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
            index = ord(word.azWord[i])-ord('a')  
            buckets[index].append(word)   
            List[:] = []   
    for containedList in buckets:  
        List.extend(containedList)
    return List #returns an alphabetized list

现在它在这里给我一个错误:

for containedList in buckets:

它说" UnboundLocalError:局部变量'桶'在转让之前引用"。这是什么意思?

3 个答案:

答案 0 :(得分:1)

for i in range (length-1, -1, -1):    #for every letter "column"
    for word in List:    #for every word 
        index = ord(word.azWord[i])-ord('a')   #get the index of the word
        buckets[index].append(word)     #add word object to correct bucket

让我们来看看这段代码。在外部循环的第一次迭代中,您将所有单词放在存储桶中。在第二次迭代中,您将所有单词再次放入中。每次进一步迭代都会一次又一次地发生;只有在你完成所有工作后,才能将这些文字从桶中取出并将它们放回原始列表中。

在基数排序中,排序时,需要在外循环的每次迭代中创建一组新的桶。每次完成将项目放入存储桶时,您需要使用存储桶对列表进行重新排序,而不是仅在最后执行此操作。

答案 1 :(得分:1)

根据我的评论,这应该是

def radix_sort(List, length):
    for i in range (length-1, -1, -1):    #for every letter "column"
        # Here buckets are created for each iteration
        buckets = [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
        for word in List:    #for every word 
            index = ord(word.azWord[i])-ord('a')   #get the index of the word
            buckets[index].append(word)     #add word object to correct bucket
        # Here List is reconstructed for each iteration
        List[:] = []
        for containedList in buckets:
            List.extend(containedList)

答案 2 :(得分:0)

在排队时使用列表解析。这将使您的代码更容易阅读,因为没有人想要计算所有这些空箱。

buckets = [[] for i in range(26)]

另外,另一种获取存储区索引的方法,而不是分配变量,只需将这些计算放在索引中。

buckets[((ord(letter)/10**i)%10) for letter in word]