简体   繁体   中英

Implementing merge-sort in python

I am trying to implement the merge-sort algorithm in Python 3. Here's the function that implements the merge part of the algorithm:

def Merge(A,p,q,r):
n1 = q - p + 1
n2 = r - q

#We first populate two lists that contain the sorted subsequences A[p,...,q] and A[q+1,...,r]
L = []
R = []

for index in range(n1):
    L.append(A[index + p])

for index in range(n2):
    R.append(A[index + q + 1])

#We now overwrite the A[p,..,q,...r] section of the list by comparing the 'top-most'
#elements in the lists l and R and putting the smaller element in the corresponding
#entry in A. If one of the list is fully exposed/no longer available, we simply put the 
#remaining list's elements in the corresponding positions in A.

i = 0
j = 0

for k in range(r - p + 1 ):

    if i > n1-1:
        A[k] = R[j]
        j = j + 1

    elif j > n2-1:
        A[k] = L[i]
        i = i + 1

    elif L[i] < R[j]:
        A[k] = L[i]
        i = i + 1

    else:
        A[k] = R[j]
        j = j + 1 

return A   

I have tested this function and it runs fine: as long as the subarrays A[p,q] and A[q+1,r] are sorted, the whole array A[p,r] will be sorted correctly. I now try and implement a divide and conquer approach to merge a large enough list.

import math

def Merge_Sort(A,p,r):

if p == r:

    return A

if p < r:

    q = math.floor((p+r)/2)
    Merge_Sort(A,p,q)
    Merge_Sort(A,q+1,r)
    Merged_List = Merge(A,p,q,r)

return Merged_List

But I get erroneous answers when I run it. Here's an example:

#We now analyze the merge sort algorithm.
A = [1,7,9,3]
B = Merge_Sort(A,0,3)
print(B)

The output is

[3, 9, 3, 9]

I am probably making some obvious/stupid mistake in the implementation of the divide and conquer bit. Suggestions?

The error is in the assignments to A[k] . They should be changed to assignments to A[p+k] .

Note that L and R can be defined using the following syntax (no explicit loop):

L = A[p:q+1]
R = A[q+1:r+1]

To be consistent with how native functions work in Python (eg list.extend ), your two functions should not return the list. They mutate the list that you pass as argument, and so to avoid confusion, it is better not to return it: it could make users of your code think that the function has no side effects.

In Merge Sort Algorithm, We first divide the array into two parts recursively, then sort each part and merge them recursively.So, Its a divide and conquer algorithm.

MergeSort(arr[], l,  r)
If r > l
     1. Find the middle point to divide the array into two halves:  
             middle m = (l+r)/2
     2. Call mergeSort for first half:   
             Call mergeSort(arr, l, m)
     3. Call mergeSort for second half:
             Call mergeSort(arr, m+1, r)
     4. Merge the two halves sorted in step 2 and 3:
             Call merge(arr, l, m, r)

I think your code have problem in the merge function.Where you should assign the elements of array L and array R. Your starting index is p, Therefore you should assign L[i] and R[i] to A[p+k] instead of A[k]. If you still have doubts regarding merge sort refer to Merge Sort . hope this solves all your queries. Thanks

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