Mergesort with Python

merge sort python recursive
quick sort python
3 way merge sort python
merge sort algorithm with example
merge sort c#
merge sort complexity
merge sort in python w3resource
merge sort in c using recursion

I couldn't find any working Python 3.3 mergesort algorithm codes, so I made one myself. Is there any way to speed it up? It sorts 20,000 numbers in about 0.3-0.5 seconds

def msort(x):
    result = []
    if len(x) < 2:
        return x
    mid = int(len(x)/2)
    y = msort(x[:mid])
    z = msort(x[mid:])
    while (len(y) > 0) or (len(z) > 0):
        if len(y) > 0 and len(z) > 0:
            if y[0] > z[0]:
                result.append(z[0])
                z.pop(0)
            else:
                result.append(y[0])
                y.pop(0)
        elif len(z) > 0:
            for i in z:
                result.append(i)
                z.pop(0)
        else:
            for i in y:
                result.append(i)
                y.pop(0)
    return result

You can initialise the whole result list in the top level call to mergesort:

result = [0]*len(x)   # replace 0 with a suitable default element if necessary. 
                      # or just copy x (result = x[:])

Then for the recursive calls you can use a helper function to which you pass not sublists, but indices into x. And the bottom level calls read their values from x and write into result directly.

That way you can avoid all that poping and appending which should improve performance.

Python Program for Merge Sort, Python Program for Merge Sort. Merge Sort is a Divide and Conquer algorithm. It divides input array in two halves, calls itself for the two halves and then merges the two sorted halves. The merge() function is used for merging two halves. Working of Merge Sort in Python. Merge sort is a general-purpose sorting technique purely based on Divide and Conquer Approach. In the Divide and Conquer technique, the elements are divided into smaller parts or lists. Then the appropriate function is applied to each half of the main input list. Further, the halves are merged together to get the result.

The first improvement would be to simplify the three cases in the main loop: Rather than iterating while some of the sequence has elements, iterate while both sequences have elements. When leaving the loop, one of them will be empty, we don't know which, but we don't care: We append them at the end of the result.

def msort2(x):
    if len(x) < 2:
        return x
    result = []          # moved!
    mid = int(len(x) / 2)
    y = msort2(x[:mid])
    z = msort2(x[mid:])
    while (len(y) > 0) and (len(z) > 0):
        if y[0] > z[0]:
            result.append(z[0])
            z.pop(0)
        else:
            result.append(y[0])
            y.pop(0)
    result += y
    result += z
    return result

The second optimization is to avoid popping the elements. Rather, have two indices:

def msort3(x):
    if len(x) < 2:
        return x
    result = []
    mid = int(len(x) / 2)
    y = msort3(x[:mid])
    z = msort3(x[mid:])
    i = 0
    j = 0
    while i < len(y) and j < len(z):
        if y[i] > z[j]:
            result.append(z[j])
            j += 1
        else:
            result.append(y[i])
            i += 1
    result += y[i:]
    result += z[j:]
    return result

A final improvement consists in using a non recursive algorithm to sort short sequences. In this case I use the built-in sorted function and use it when the size of the input is less than 20:

def msort4(x):
    if len(x) < 20:
        return sorted(x)
    result = []
    mid = int(len(x) / 2)
    y = msort4(x[:mid])
    z = msort4(x[mid:])
    i = 0
    j = 0
    while i < len(y) and j < len(z):
        if y[i] > z[j]:
            result.append(z[j])
            j += 1
        else:
            result.append(y[i])
            i += 1
    result += y[i:]
    result += z[j:]
    return result

My measurements to sort a random list of 100000 integers are 2.46 seconds for the original version, 2.33 for msort2, 0.60 for msort3 and 0.40 for msort4. For reference, sorting all the list with sorted takes 0.03 seconds.

Merge sort in Python, Merge sort works by splitting the input list into two halves, repeating the process on those halves, and finally merging the two sorted halves together. The algorithm first moves from top to bottom, dividing the list into smaller and smaller parts until only the separate elements remain. In python, merge sort is defined as one of the sorting algorithms which is general-purpose, uses comparison based sorting by divide and conquer algorithm where the idea is to break down the list into sub-lists until each sub-list has max one element and merge all the sub-lists in reverse order to get the sorted sub-lists and finally a single list which is sorted is called merge sort.

Code from MIT course. (with generic cooperator )

import operator


def merge(left, right, compare):
    result = []
    i, j = 0, 0
    while i < len(left) and j < len(right):
        if compare(left[i], right[j]):
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    while i < len(left):
        result.append(left[i])
        i += 1
    while j < len(right):
        result.append(right[j])
        j += 1
    return result


def mergeSort(L, compare=operator.lt):
    if len(L) < 2:
        return L[:]
    else:
        middle = int(len(L) / 2)
        left = mergeSort(L[:middle], compare)
        right = mergeSort(L[middle:], compare)
        return merge(left, right, compare)

Merge Sort in Python, Merge Sort is one of the most famous sorting algorithms due to its efficient, general-purpose usage. It's a classic example of a divide-and-conquer algorithm. You should avoid changing the list anyway when iterating over it. – poke Sep 12 '13 at 10:33. Also, there is probably nothing specific to Python 3.3 in an ordinary implementation of mergesort so you can just Google for "python mergesort" and use any implementation you find, even if it is for older versions.

def merge_sort(x):

    if len(x) < 2:return x

    result,mid = [],int(len(x)/2)

    y = merge_sort(x[:mid])
    z = merge_sort(x[mid:])

    while (len(y) > 0) and (len(z) > 0):
            if y[0] > z[0]:result.append(z.pop(0))   
            else:result.append(y.pop(0))

    result.extend(y+z)
    return result

6.11. The Merge Sort, Merge sort is a recursive algorithm that continually splits a list in half. If the list If​, on the other hand, the length is greater than one, then we use the Python slice  Merge Sort Python Now we have only one element in each subarray, so it’s time to merge them. We have to merge them in the same manner as had divided it, but in sorted manner. Step 3: C ompare 2 with 6 and 1 with 4, and place them in sorted order.

Take my implementation

def merge_sort(sequence):
    """
    Sequence of numbers is taken as input, and is split into two halves, following which they are recursively sorted.
    """
    if len(sequence) < 2:
        return sequence

    mid = len(sequence) // 2     # note: 7//2 = 3, whereas 7/2 = 3.5

    left_sequence = merge_sort(sequence[:mid])
    right_sequence = merge_sort(sequence[mid:])

    return merge(left_sequence, right_sequence)

def merge(left, right):
    """
    Traverse both sorted sub-arrays (left and right), and populate the result array
    """
    result = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result += left[i:]
    result += right[j:]

    return result


print merge_sort([5, 2, 6, 8, 5, 8, 1])

Python Data Structures and Algorithms: Merge sort, Python Exercises, Practice and Solution: Write a Python program to sort a list of elements using the merge sort algorithm. Python Merge Sort Here you will learn about python merge sort algorithm. Merge sort is based on divide and conquer technique. All we have to do is divide our array into 2 parts or sub-arrays and those sub-arrays will be divided into other two equal parts.

Merge Sort: A Quick Tutorial and Implementation Guide, Python data structures - Lists; Recursion. What is Merge Sort? We are in the fourth tutorial of the sorting series. The previous  Merge sort walkthrough with code in Python History. Step 1- split. Every element in the list above consistent of a tuple. The first element of the tuple is the input and Step 2- merge sorted lists. Given two sorted lists we should be able to “merge” them into a single list in a linear Step 3-

Merge sort walkthrough with code in Python - Amir Ziai, Step 2- merge sorted lists. Given two sorted lists we should be able to “merge” them into a single list in a linear operation. The Linux kernel uses merge sort for its linked lists.Python uses Timsort, another tuned hybrid of merge sort and insertion sort, that has become the standard sort algorithm in Java SE 7, on the Android platform, and in GNU Octave. External links

Mergesort with Python, You can initialise the whole result list in the top level call to mergesort: result = [0​]*len(x) # replace 0 with a suitable default element if necessary. # or just copy x  Merge Sort. 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) The following

Comments
  • You should not pop from lists, as that will unecessarily shift the array elements over and over. You should avoid changing the list anyway when iterating over it.
  • Also, there is probably nothing specific to Python 3.3 in an ordinary implementation of mergesort so you can just Google for "python mergesort" and use any implementation you find, even if it is for older versions. For instance, this one: geekviewpoint.com/python/sorting/mergesort
  • The question is too old but isn't it using more memory for result array merge sort already uses double memory of array to sort it we are again producing the array in result.
  • Using sorted() feels like cheating.
  • I tried your msort3 method in python 2.7.6 but I got the following error - Traceback (most recent call last): File "mergesort.py", line 21, in <module> msort3([5,24, 87, 55, 32, 1, 45]); File "mergesort.py", line 6, in msort3 y = msort3(x[:mid]) File "mergesort.py", line 10, in msort3 while i < len(y) and j < len(z): TypeError: object of type 'NoneType' has no len()
  • I tried the same msort3 method in python 3.4.0 and got the following error - [24, 87] Traceback (most recent call last): File "mergesort.py", line 21, in <module> msort3([5,24, 87, 55, 32, 1, 45]); File "mergesort.py", line 6, in msort3 y = msort3(x[:mid]) File "mergesort.py", line 10, in msort3 while i < len(y) and j < len(z): TypeError: object of type 'NoneType' has no len()
  • @AbhishekPrakash: I cannot reproduce the error in Python 2.7.5. Will try latter on another machine. Are the return statements well written?
  • @AbhishekPrakash: I ran your test without problems under Python 2.7.6 and Python 3.4.0 (Ubuntu 14.04). If you used print rather than return, the function returns None (as no return is found) and breaks the recursivity.
  • After we are outside the first while loop: we can do: if len(left) == i: result.extend(right[j:]) else: result.extend(left[i:])
  • you are creating new list instead of modifying the original...not a good idea!
  • very minimalistic approach but using extend() fails to demonstrate the concept/algorithm for merge....I mean what's a merge sort without the merge algorithm implementation !
  • returns error: slice indices must be integers or None or have an index method
  • Working fine with Python 2.7.5