mergesort,递归基本案例和排序问题

时间:2014-10-19 23:26:29

标签: python recursion

我在Mergesort算法的Python中做了以下实现:

def mergeSort(listNumbers,ini,end):
    if ini==end:
        return listNumbers
    else:
        mid=(ini+end)/2
        mergeSort(listNumbers,ini,mid)
        mergeSort(listNumbers,mid+1,end)
        merge(listNumbers,ini,mid,end)

def merge(listNumbersT,ini,mid,end):
    b=[]
    ind1=ini
    ind2=mid+1
    while ind1<=mid and ind2<=end:
        if listNumbersT[ind1]<listNumbersT[ind2]:
            b.append(listNumbersT[ind1])
            ind1=ind1+1
        else:
            b.append(listNumbersT[ind2])
            ind2=ind2+1
    while ind1<=mid:
        b.append(listNumbersT[ind1])
        ind1=ind1+1
    while ind2<=end:
        b.append(listNumbersT[ind2])
        ind2=ind2+1
    listNumbersT=b
    print listNumbersT

def main():
    l=[4,1,8,2,5,9,10]
    print mergeSort(l,0,len(l)-1)

if __name__=="__main__":
    main()

我不知道如何修复我对mergeSort的递归调用的基本情况,当我运行程序时它打印None;并且我必须打印最终结果的唯一方法是添加:

print listNumbersT

在合并功能中,我该如何解决这个问题?它似乎也没有命令列表的最后一个元素。

任何帮助?

由于

2 个答案:

答案 0 :(得分:3)

我通过在原地进行排序来实现这一目标。在某些地方,你正在返回名单,其他地方则没有那么多。

修订后的mergeSort函数如下所示:

def mergeSort(listNumbers,ini,end):
    if ini < end:
        mid=(ini+end)/2
        mergeSort(listNumbers,ini,mid)
        mergeSort(listNumbers,mid+1,end)
        merge(listNumbers,ini,mid,end)

这意味着基本情况是ini >= endlistNumbers保持不变。

merge功能结束时,我将listNumbersT = b替换为:

    for i,value in enumerate(b):
        listNumbersT[ini + i] = value

b的元素复制回原始listNumbersT。再次,这使得变化&#34;就地&#34;在原始列表中,因此不需要返回任何内容。

这就是main

def main():
    l=[4,1,8,2,5,9,10]
    mergeSort(l,0,len(l)-1)   # sort l in-place
    print l                   # [1, 2, 4, 5, 8, 9, 10]

小调整 - 将mergeSort函数的开头更改为

def mergeSort(listNumbers,ini=0,end=-1):
    if end < 0:
        end += len(listNumbers)

main中的调用变得简单:

mergeSort(l)

使用户稍微容易一些。

答案 1 :(得分:0)

不要太多改变你的代码,

在您的函数merge中,行listNumbersT=b重新分配变量listNumbersT,因此您会丢失您在那里的值,从而导致递归。

要解决此问题,请通过以下循环替换函数listNumbersT=b中的merge

for i,number in enumerate(b):
    listNumbersT[ini + i] = number

要获得正确的返回,您需要在mergeSort函数结束时返回,例如

def mergeSort(listNumbers,ini,end):
    if ini==end:
        return listNumbers
    else:
        mid=(ini+end)/2
        mergeSort(listNumbers,ini,mid)
        mergeSort(listNumbers,mid+1,end)
        merge(listNumbers,ini,mid,end)

    return listNumbers

但是,l会被重新排序,因此您不需要在mergeSort结束时返回。

干杯