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.go
package main
import "fmt"
func mergeSort(values []int) []int {
if len(values) <= 1 {
return values
}
mid := len(values) / 2
left := mergeSort(values[:mid])
right := mergeSort(values[mid:])
merged := []int{}
i, j := 0, 0
for i < len(left) && j < len(right) {
if left[i] <= right[j] {
merged = append(merged, left[i])
i++
} else {
merged = append(merged, right[j])
j++
}
}
merged = append(merged, left[i:]...)
merged = append(merged, right[j:]...)
return merged
}
func main() {
arr := []int{5, 1, 4, 2, 8}
fmt.Println(mergeSort(arr))
}
Complexity
- Time: O(n log n)
- Space: O(n)
- Stable: yes
Implementation notes
- Go builds
arrwith the slice literal[]int{5, 1, 4, 2, 8}. Recursive calls split it with slice rangesvalues[:mid]andvalues[mid:], which share the same backing array until merged results are allocated. mergeSort(values []int) []intreturns a sorted slice; it does not mutatevaluesin place during merge.- Each merge starts with
merged := []int{}and grows that result withappend, so merged output may allocate backing arrays as it grows. - Merge cursors
iandjwalkleftandright; the comparisonleft[i] <= right[j]keeps equal values from the left side first. - Remainders are appended with variadic slice expansion:
append(merged, left[i:]...)andappend(merged, right[j:]...). - The trace records split
[5, 1]and[4, 2, 8], sorted halves[1, 5]and[2, 4, 8], and final merged result[1, 2, 4, 5, 8]. fmt.Println(mergeSort(arr))prints Go's default slice format[1 2 4 5 8], without commas.
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.