【问题标题】:How can i stop this recursion?我怎样才能停止这种递归?
【发布时间】:2017-11-23 22:41:26
【问题描述】:

我正在做一个排序奖牌表的函数。例如:如果两支或多支球队的金牌数量相同,则从多到少评判银牌,然后是铜牌。

列表中的每个列表都是一个国家[金、银、铜]:

[[1, 2, 0], [0, 1, 0], [2, 0, 0], [0, 0, 3]]

那就是回报:

[[2, 0, 0], [1, 2, 0], [0, 1, 0], [0, 0, 3]]  

我的函数正在运行,但我找不到停止递归的方法...

代码:

def ordem(lista,lista2,x):
    cond=0
    cond2=0
    cond3=0
    cont2=0
    for xx in lista:
        if x-cont2==1:
            break
        if lista[cont2+1][0] > lista[cont2][0]:
            lista[cont2+1],lista[cont2]=lista[cont2],lista[cont2+1]
            lista2[cont2+1],lista2[cont2]=lista2[cont2],lista2[cont2+1]
            cond=1
            cond2=1
            #print("1")
            #cont2+=1
        if lista[cont2+1][1] > lista[cont2][1] and cond2 ==0:
            lista[cont2+1],lista[cont2]=lista[cont2],lista[cont2+1]
            lista2[cont2+1],lista2[cont2]=lista2[cont2],lista2[cont2+1]
            cond=1
            cond3=1
            #print("2")
            #cont2+=1
        if lista[cont2+1][2] > lista[cont2][2] and (cond2==0 and cond3==0):
            lista[cont2+1],lista[cont2]=lista[cont2],lista[cont2+1]
            lista2[cont2+1],lista2[cont2]=lista2[cont2],lista2[cont2+1]
            cond=1
            #print("3")
            #cont2+=1


        #else: cond=False
        cont2+=1
    if cond!=1:
        #print(lista)
        return lista2

    #print(lista)
    #print("cond:"+str(cond))
    return ordem(lista,lista2,x)

我尝试将已经排序的元素添加到列表中,然后在进行切换时检查它们是否在其中,但它也不起作用

【问题讨论】:

  • 请修正缩进。提示:将前两行放回原处,选择整个代码块并按下编辑器工具栏上的代码按钮({})。

标签: python-3.x recursion


【解决方案1】:

为什么不使用 Python sorted 而不是构建自己的排序算法?

from operator import itemgetter 

medals = [[1, 2, 0], [0, 1, 0], [2, 0, 0], [0, 0, 3]]
res = sorted(medals, key=itemgetter(0,1,2), reverse=True)
print (res)

输出:

[[2, 0, 0], [1, 2, 0], [0, 1, 0], [0, 0, 3]]

或者直接改变原始列表进行排序:

medals.sort(key=itemgetter(0,1,2), reverse=True)

快速排序实现

在 cmets 中,您提到不允许使用 sortsorted。在这种情况下,您可以使用以下 QuickSort 实现:

def quick_sort(lst, cmp):
    def recurse(first, last):
        if first >= last:
            return
        pivotvalue = lst[first]
        left = first + 1
        right = last
        while True:
            while left <= right and cmp(lst[left], pivotvalue) < 0:
                left += 1
            while left <= right and cmp(lst[right], pivotvalue) > 0:
                right -= 1
            if left > right:
                break
            lst[left], lst[right] = lst[right], lst[left]
        lst[first], lst[right] = lst[right], pivotvalue
        recurse(first, right-1)
        recurse(left, last)

    recurse(0, len(lst)-1)

def medals_compare(a, b):
    if a[0] != b[0]:
        return b[0] - a[0]
    if a[1] != b[1]:
        return b[1] - a[1]
    return b[2] - a[2]

medals = [[1, 2, 0], [0, 1, 0], [2, 0, 0], [0, 0, 3]]
quick_sort(medals, medals_compare)
print(medals)

【讨论】:

  • 是的,这会容易得多。但是我的老师不希望我们使用现成的排序功能来解决这个问题:/
  • 如果一定要自己写,那么应该实现哪种排序算法:快速排序、归并排序、插入排序、堆排序、冒泡排序……?
  • 我在写代码的时候并没有想到这一点,但我认为这看起来像一个快速排序
  • 我添加了一个快速排序实现。