Sorting
Merge Sort (Top-Down)
Split the array recursively, sort each half, then merge two sorted runs into one sorted result.
Algorithm
Basic Implementation
basic.py
def merge_sort(values):
if len(values) <= 1:
return values
mid = len(values) // 2
left = merge_sort(values[:mid])
right = merge_sort(values[mid:])
merged = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
merged.append(left[i])
i += 1
else:
merged.append(right[j])
j += 1
merged.extend(left[i:])
merged.extend(right[j:])
return merged
arr = [5, 1, 4, 2, 8]
print(merge_sort(arr))
Complexity
- Time: O(n log n)
- Space: O(n)
- Stable: yes
Implementation notes
- Python slicing creates new list objects for
values[:mid]andvalues[mid:]; those lists hold references to the same immutableintobjects, not copies of the integer values themselves. - Each
merge_sortcall uses a normal Python call-stack frame.merged = []allocates the temporary output list,appendadds one selected element at a time, andextend(left[i:])/extend(right[j:])appends the remaining sliced tail. - The comparison is
left[i] <= right[j], so ties would take the left element first and preserve stability. The originalarris not mutated; the replay shows the newly returned left/right lists and the final merged list, with temporary lists later handled by Python GC.
divide and conquer
Each recursive call solves a smaller sorted subproblem.
merge step
Two sorted halves are combined by repeatedly taking the smaller front item.