def merge(elements):
    """Merge Sort algorithm

    Uses merge sort recursively to sort a list of elements

    Parameters
    elements: List of elements to be sorted

    Returns
    list of sorted elements
    """
    def list_merge(a, b):
        """Actual "merge" of two lists

        Compares every member of a list and returns a new list with
        sorted elements

        Parameters
        a, b: Lists of elements to be sorted

        Returns
        list of sorted elements
        """
        #initialize some values
        len_a = len(a)
        len_b = len(b)
        a_i = b_i = 0
        c = []
        
        for i in range(len_a + len_b):
            #check which element is the smaller
            #and place it into c list
            if a_i < len_a and b_i < len_b:
                if a[a_i] < b[b_i]:
                    c.append(a[a_i])
                    a_i = a_i+1
                else:
                    c.append(b[b_i])
                    b_i = b_i+1
            else:
                #when we are done with one list append pending values of the other one
                if a_i == len_a:
                    # append all pending b values into c
                    return c + b[b_i:]
                if b_i == len_b:
                    # same as above but with a values
                    return c + a[a_i:]


    length = len(elements)
    if length <= 1:
        #ending condition
        return elements

    half = int(length/2)

    #recursive call for both halfs of elements
    #divide and conquer
    return list_merge(merge(elements[:half]), merge(elements[half:]))