Recursively splits the array in half until each sub-array holds a single element, then merges adjacent sub-arrays back together in sorted order, building the fully sorted array bottom-up through the call stack.
Stable and guarantees O(n log n) in all cases, but requires an auxiliary array of the same size as the input to perform each merge step, the classic space-vs-stability trade-off.