在Python3中合并排序

时间:2016-04-18 01:43:16

标签: python python-3.x mergesort

我有一些工作代码,但我不太明白为什么它有效。如果有人可以通过我的一些部分,或解释我在我的假设中的错误,我会非常感激。

以下是代码:

def mergeSort(alist):
    print("Splitting ",alist)
    if len(alist)>1:
        mid = len(alist)//2
        lefthalf = alist[:mid]
        righthalf = alist[mid:]

        mergeSort(lefthalf)
        mergeSort(righthalf)

        i=0
        j=0
        k=0
        while i < len(lefthalf) and j < len(righthalf):
            if lefthalf[i] < righthalf[j]:
                alist[k]=lefthalf[i]
                i=i+1
            else:
                alist[k]=righthalf[j]
                j=j+1
            k=k+1

        while i < len(lefthalf):
            alist[k]=lefthalf[i]
            i=i+1
            k=k+1

        while j < len(righthalf):
            alist[k]=righthalf[j]
            j=j+1
            k=k+1
    print("Merging ",alist)

alist = [54,26,93,17,77,31,44,55,20]
mergeSort(alist)
print(alist)

如果我理解正确,该函数会反复划分列表的左半部分,创建越来越小的子列表,直到它们只有一个项目长,然后移到右半部分。那是对的吗? EX:list = [1,2,3,4,5,6,7,8]将分为[1,2,3,4]和[5,6,7,8],然后函数会中断左半部分进入[1,2]和[3,4],然后[1,2]进入[1]和[2]然后向后工作。下一步是将[3,4]分解为[3]和[4],然后返回[5,6,7,8]并重复所有相同的步骤。这是对的吗?

我的另一个问题是,为了重新组合所有的小子列表,我和j必须重置为0吗? EX:对于[1]和[2]成为[1,2] i和j变为1,但是他们不能指向[3]和[4]成为[3,4],因为它们都在索引0.我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

不要考虑整个程序。递归思考。谁在乎哪个列表首先被拆分?您需要知道的是:

  • 基本情况是否正确?在这种情况下,您可以通过什么都不做来排序1个或更少元素的列表?答案是肯定的。
  • 递归调用是否接近基本情况?在这种情况下,list参数逐渐变小,最终长度为0或1,所以是的。
  • 最后但并非最不重要的是......假设递归调用执行它们应该执行的操作,函数的其余部分是否相应地运行?在这种情况下,如果你拆分alist,对每一半进行排序,并将两半合并,就像3 while循环一样,合并到alist,它是否已排序?答案是肯定的。

对于您的其他问题,一次通话中的ijk完全独立于其他通话中的问题。即使它们不是,它们也会在0循环开始之前设置为while