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.scala
object Main {
def mergeSort(values: List[Int]): List[Int] = {
if (values.length <= 1) return values
val (leftRaw, rightRaw) = values.splitAt(values.length / 2)
val left = mergeSort(leftRaw)
val right = mergeSort(rightRaw)
merge(left, right)
}
def merge(left: List[Int], right: List[Int]): List[Int] = (left, right) match {
case (Nil, _) => right
case (_, Nil) => left
case (l :: ls, r :: rs) =>
if (l <= r) l :: merge(ls, right) else r :: merge(left, rs)
}
def main(args: Array[String]): Unit = {
val arr = List(5, 1, 4, 2, 8)
println(mergeSort(arr).mkString("[", ", ", "]"))
}
}
Complexity
- Time: O(n log n)
- Space: O(n)
- Stable: yes
Implementation notes
- This checked Scala source uses
List[Int], notArray[Int]:val arr = List(5, 1, 4, 2, 8). mergeSort(values: List[Int]): List[Int]produces a sortedList[Int]without mutating the input list; base and leftover cases can return existing list values directly.- The base case
if (values.length <= 1) return valuesstops recursion for empty and single-element lists. val (leftRaw, rightRaw) = values.splitAt(values.length / 2)splits the list into two list halves, thenval leftandval righthold the recursive sorted results.merge(left, right)uses pattern matching:Nilreturns the leftover other list, andl :: ls/r :: rsexposes each front value.- The comparison
if (l <= r)keeps equal values from the left side first, then builds the output with::cons cells. - The trace shows
[5, 1, 4, 2, 8]splitting into[5, 1]and[4, 2, 8], those halves sorting to[1, 5]and[2, 4, 8], then merging to[1, 2, 4, 5, 8]. println(mergeSort(arr).mkString("[", ", ", "]"))prints the final list as[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.