简体   繁体   中英

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. 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. 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? 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?

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? 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.
  • 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? 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. And even if they weren't, they're being set to 0 just before the while loops start anyways.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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