evehsu
evehsu

Reputation: 39

merge sort/recursion in python

I understand how merge sort work but however when I try to implement in python, I think I am still a little confused about how things are really working out on stack. I have a function called merge_sorted_list which is used for merging two sorted list and a function called merge_sort1 and merge_sort2, which are accounted for the recursion process. "merge_sort1" and "merge_sort2" are very similar but only merge_sort2 gave the correct answer. It looks like merge_sort1 was not taking the returned value at each level of the stack. Could anyone tell me what is the difference in the evaluation between merge_sort1 and merge_sort2 please?

def merge_sorted_list(list1,list2):

    if(len(list1) == 0 or len(list2) == 0):
        print('input error')
        return;

    i = 0
    j = 0
    k = 0
    list_merge = [0]*(len(list1) + len(list2))
    while(i < len(list1) and j < len(list2)):
        if (list1[i] < list2[j]):
            list_merge[k] = list1[i]
            i += 1
        else:
            list_merge[k] = list2[j]
            j += 1
        k += 1
    while(i < len(list1)):
        list_merge[k] = list1[i]
        i += 1
        k += 1
    while (j < len(list2)):
        list_merge[k] = list2[j]
        j += 1
        k += 1
    return(list_merge)

def merge_sort1(mylist):
    print("splitting ",mylist)
    if (len(mylist) > 1):
        mid = len(mylist)//2
        merge_sort1(mylist[:mid])
        merge_sort1(mylist[mid:])

    #   lefthalf = mylist[:mid]
    #   righthalf = mylist[mid:]

    #   merge_sort1(lefthalf)
    #   merge_sort1(righthalf)

        mylist[:] = merge_sorted_list(mylist[:mid],mylist[mid:])
        print("merging result ",mylist)
    return mylist

def merge_sort2(mylist):
    print("splitting ",mylist)
    if (len(mylist) > 1):

        mid = len(mylist)//2
#       merge_sort2(mylist[:mid])
#       merge_sort2(mylist[mid:])

        lefthalf = mylist[:mid]
        righthalf = mylist[mid:]

        merge_sort2(lefthalf)
        merge_sort2(righthalf)

        mylist[:] = merge_sorted_list(lefthalf,righthalf)
        print("merging result ",mylist)
    return mylist

if we try merge_sort1([4,67,3,3,2,6]), the output will be

('splitting ', [4, 67, 3, 3, 2, 6])
('splitting ', [4, 67, 3])  
('splitting ', [4])
('splitting ', [67, 3])
('splitting ', [67])
('splitting ', [3])
('merging result ', [3, 67])
('merging result ', [4, 67, 3])
('splitting ', [3, 2, 6])
('splitting ', [3])
('splitting ', [2, 6])
('splitting ', [2])
('splitting ', [6])
('merging result ', [2, 6])
('merging result ', [2, 3, 6])
('merging result ', [3, 2, 4, 6, 67, 3])

The output of merge_sort2([4,67,3,3,2,6]) will be

('splitting ', [4, 67, 3, 3, 2, 6])
('splitting ', [4, 67, 3])
('splitting ', [4])
('splitting ', [67, 3])
('splitting ', [67])
('splitting ', [3])
('merging result ', [3, 67])
('merging result ', [3, 4, 67])
('splitting ', [3, 2, 6])
('splitting ', [3])
('splitting ', [2, 6])
('splitting ', [2])
('splitting ', [6])
('merging result ', [2, 6])
('merging result ', [2, 3, 6])
('merging result ', [2, 3, 3, 4, 6, 67])

Thank you very much

Upvotes: 0

Views: 1898

Answers (1)

John Coleman
John Coleman

Reputation: 51998

mylist[:mid] returns a list. In list_sort1 you are (attempting to) sort this list and then promptly discarding it. Later on, you are using a second (unmodified) instance of mylist[:mid]. Etc. for mylist[mid:]. On the other hand, in the second version you are assigning the results of mylist[:mid] etc. to variables and hence not discarding the result of sorting them.

Upvotes: 1

Related Questions