Merge sort
Merge sort is a divide-and-conquer algorithm for sorting which has a time complexity of O(n log n). It goes as follows given a sequence S of n elements:
1. Base case: If the sequence has a single element or no elements, it is sorted and we're done.
2. Divide step: Split the sequence in the middle, obtaining subsequences A and B.
3. Recursion step: Apply merge sort to each of the subsequences A and B, which will now be sorted.
4. Merge step: Take the smallest element between the sorted A and B subsequences by checking the next element of each from the start. If there are no more elements on either A or B, take all the remaining elements of the other. Repeat this step until a sorted sequence is built with all elements of A and B, which will be the sorted sequence S.
Functional implementation
# NOTE: assuming both "a" and "b" are sorted sequences.
# "c" acts as the accumulator for the resulting merged sequence.
def merge_sorted_sequences(a, b, c=[]):
# if either sequence is empty, return the other (base case)
if len(a) == 0: return c + b
if len(b) == 0: return c + a
# take the smallest element of either "a" or "b" and build
# up the resulting sorted sequence "c"
if a[0] <= b[0]:
return merge_sorted_sequences(a[1:], b, c + [a[0]])
else:
return merge_sorted_sequences(a, b[1:], c + [b[0]])
def merge_sort(arr):
if len(arr) <= 1: return arr # base case
m = len(arr) // 2 # midpoint of "arr"
p, q = arr[:m], arr[m:] # divide step
a, b = merge_sort(p), merge_sort(q) # recursion step
return merge_sorted_sequences(a, b) # conquer step
Source
- “Introduction to Algorithms” by Thomas H. Cormen et al. (2022).