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.swift
func mergeSort(_ values: [Int]) -> [Int] {
if values.count <= 1 { return values }
let mid = values.count / 2
let left = mergeSort(Array(values[..<mid]))
let right = mergeSort(Array(values[mid...]))
var merged: [Int] = []
var i = 0
var j = 0
while i < left.count && j < right.count {
if left[i] <= right[j] {
merged.append(left[i])
i += 1
} else {
merged.append(right[j])
j += 1
}
}
merged.append(contentsOf: left[i...])
merged.append(contentsOf: right[j...])
return merged
}
let arr = [5, 1, 4, 2, 8]
print(mergeSort(arr))
Complexity
- Time: O(n log n)
- Space: O(n)
- Stable: yes
Implementation notes
mergeSort(_ values: [Int]) -> [Int]takes an immutable Swift[Int]value and returns a newly built sorted array instead of mutatingarr.- The base case
values.count <= 1returns the current array value directly. let mid = values.count / 2splits the input, andArray(values[..<mid])plusArray(values[mid...])copy the slice ranges before the recursive calls.let leftandlet righthold sorted recursive results;var merged: [Int]is the only merge buffer built by the current call.var iandvar jwalk the two sorted halves whilei < left.count && j < right.count;left[i] <= right[j]keeps equalIntvalues from the left half first.- Merge output grows through
merged.append(...), thenappend(contentsOf:)copies any remaining suffix fromleft[i...]orright[j...]. - The trace shows
[5, 1, 4, 2, 8]splitting into[5, 1]and[4, 2, 8], those halves becoming[1, 5]and[2, 4, 8], then the final merge producing[1, 2, 4, 5, 8]. print(mergeSort(arr))uses Swift's array display form and outputs[1, 2, 4, 5, 8].
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.