简体   繁体   English

Python3中的合并排序

[英]Merge Sort in Python3

I have some working code, but I just don't quite understand why it works.我有一些有效的代码,但我不太明白它为什么有效。 If someone could walk me through a few pieces of it, or explain where I am mistaken in my assumptions, I would really appreciate it.如果有人可以带我浏览其中的几部分,或者解释我的假设错误的地方,我将不胜感激。

Here is the code:这是代码:

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)

If I understand correctly, the function will divide the left half of a list over and over, creating smaller and smaller sublists until they are only one item long, and then move on to the right half.如果我理解正确,该函数将一遍又一遍地划分列表的左半部分,创建越来越小的子列表,直到它们只有一个项目长,然后移到右半部分。 Is that correct?那是对的吗? EX: list=[1, 2, 3, 4, 5, 6, 7, 8] will be broken into [1, 2, 3, 4] and [5, 6, 7, 8], then the function will break the left half into [1, 2] and [3, 4], and then [1, 2] into [1] and [2] before working itself backwards. 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],然后再向后处理。 The next step is to break [3, 4] into [3] and [4] before returning to [5, 6, 7, 8] and repeating all the same steps.下一步是将 [3, 4] 分解为 [3] 和 [4],然后再返回 [5, 6, 7, 8] 并重复所有相同的步骤。 Is that correct?那是对的吗?

My other question is, shouldn't i and j have to be reset to 0 in order to recombine all the little sublists?我的另一个问题是,不应该将 i 和 j 重置为 0 以重新组合所有小子列表吗? EX: for [1] and [2] to become [1, 2] i and j become 1, but then they can't point to [3] and [4] to become [3, 4] as those are both at index 0. What am I missing here?例如:对于 [1] 和 [2] 变成 [1, 2] i 和 j 变成 1,但是他们不能指向 [3] 和 [4] 变成 [3, 4] 因为它们都在索引 0。我在这里遗漏了什么?

Don't think about the entire procedure.不要考虑整个过程。 Think recursively.递归思考。 Who cares about which list is being broken apart first?谁关心哪个列表首先被分解? All you need to know is:您只需要知道:

  • Is the base case correct?基本情况是否正确? In this case, can you sort a list of 1 or less elements by doing nothing at all?在这种情况下,您是否可以通过什么都不做来对包含 1 个或更少元素的列表进行排序? The answer's yes.答案是肯定的。
  • Do the recursive calls approach the base case?递归调用是否接近基本情况? In this case, the list argument is gradually becoming smaller, eventually having length 0 or 1 so yeah.在这种情况下,列表参数逐渐变小,最终长度为 0 或 1,所以是的。
  • And last but not least... assumming the recursive calls do what they're supposed to do, does the rest of the function behave accordingly?最后但并非最不重要的...假设递归调用做他们应该做的事情,函数的其余部分是否相应地表现? In this case, if you split alist , sort each half, and merge the two halves, like the 3 while loops do, into alist , is it sorted?在这种情况下,如果你拆分alist ,对每一半进行排序,然后将两半合并到alist ,就像 3 个 while 循环一样,它是否已排序? The answer, again, is yes.答案是肯定的。

For your other question, i , j and k on one call are completely independent of the ones in other calls.对于您的另一个问题,一次调用中的ijk完全独立于其他调用中的那些。 And even if they weren't, they're being set to 0 just before the while loops start anyways.即使它们不是,它们也会在while循环开始之前被设置为0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM