Published on

Mergesort

Authors
  • avatar
    Name
    Simon Kurbiel
    Twitter

Introduction

Merge sort is a popular sorting algorithm that uses the divide and conquer strategy.

How it works

The mergesort algorithm recursively divides an array into two halves. Then the algorithm will sort each half and merge it with it's other half. Here is an example below. image

We will now only focus on the merging part of the algorithm. We will focus on the last operation, merging the sorted halves, AA and BB of the entire array into CC.

A: 2,4,5,7B: 1,2,3,6C:\begin{align*} &A: \text{ \textcolor{red}{2},4,5,7} \\ &B: \text{ \textcolor{red}{1},2,3,6} \\ &C: \text{} \end{align*}

We first compare the smallest(first) element of AA, with the smallest (first) element of BB. The smallest of the two becomes the first element in the sorted result, CC.

A: 2,4,5,7B: 2,3,6C:1\begin{align*} &A: \text{ \textcolor{red}{2},4,5,7} \\ &B: \text{ \textcolor{red}{2},3,6} \\ &C: \text{1} \end{align*}

We now increment the list which consisted the smallest number. And the merge process is continued the same way.

A: 2,4,5,7B: 3,6C:1,2\begin{align*} &A: \text{ \textcolor{red}{2},4,5,7} \\ &B: \text{ \textcolor{red}{3},6} \\ &C: \text{1,2} \end{align*}

The merge process is continued until one of the sequences has no more elements in it. The sequences might also contain the same number of elements as in this case.

A:B:C:1,2,2,3,4,5,6,7\begin{align*} &A: \\ &B: \\ &C: \text{1,2,2,3,4,5,6,7} \end{align*}

Let M(m,n)M(m,n) be the worst-case number of key comparisons to merge two sorted sequences of length mm and nn. Then,

M(m,n)=m+n1\boxed{M(m,n) = m+n-1}

The reasoning is simple. After each comparison, one element will be popped out until only one element remains.

However, for the special case of when the two sorted sequences are of equal length, the worst-case number of comparisons becomes,

M(n2,n2)=n1\boxed{M(\frac {n}{2}, \frac {n}{2})= n-1}

What is the best-case number of key-comparisons? It is min(m,n)min(m,n). That is, all the elements of the shortest sequence are smaller than all elements of the longer sequence.

Algorithm


def merge_sort(array:list):
    if len(array) > 1:

        #find the mid point
        mid:int = len(array)//2

        #separe to a left block and right block
        L:list[int] = array[:mid]
        R:list[int] = array[mid:]

        ##sort the first hald
        merge_sort(L)

        ##sort the second half
        merge_sort(R)

        i=j=k=0

        ##copy L,R sor sorted array
        while i < len(L) and j < len(R):
            if L[i] <= R[j]:
                array[k] = L[i]
                i+=1
            else:
                array[k] = R[j]
                j+=1
            k+=1


        while i < len(L):
            array[k] = L[i]
            i+=1
            k+=1

        while j < len(R):
            array[k] = R[j]
            j+=1
            k+=1

array = [1,-2,3,90,86,89]
merge_sort(array=array)
print(array)

Analysis for special case

when n=2kn=2^k

Let T(n)T(n) be the worst-case time to sort nn elements (by recursive Mergesort). The worst-case time to recursively sort each half is T(n2)T(\frac {n}{2}). And the time to merge the two sorted halves is O(n)O(n), which means cn\le cn for some constant cc. Therefore,

f(n)={2T(n2)+cn,n2d,n=1\begin{align*} f(n) = \begin{cases} 2T(\frac {n}{2})+cn, & \quad n \ge 2 \\ d, & \quad n=1 \end{cases} \end{align*}

Solving by substitution we get

T(n)cn+2T(n2)cn+2(cn2+2T(n4))cn+cn+4T(n4)cn+cn+cn+8T(n8)3cn+23T(n23)kcn+2kT(n2k)kcn+2kT(1)kcn+d2kcnlog2n+dn\begin{align*} &T(n) \le cn+2T(\frac{n}{2}) \\ &\le cn+2(c \frac {n}{2} + 2T(\frac {n}{4})) & \le cn +cn+4T(\frac {n}{4}) \\ & \le cn+cn+cn+8T(\frac {n}{8}) \\ & \le 3cn+2^3T(\frac {n}{2^3}) \\ & \le kcn+2^k T(\frac {n}{2^k}) \\ & \le kcn+2^kT(1) \\ & \le kcn + d2^k \\ & \le cn \log_2n+dn \end{align*}

Therefore,

T(n) is O(nlog2n)\boxed{T(n) \text{ is } O(n \log_2n)}