diff --git a/src/main/scala/Sort/FunctionalMergeSort.scala b/src/main/scala/Sort/FunctionalMergeSort.scala new file mode 100644 index 0000000..1c8f285 --- /dev/null +++ b/src/main/scala/Sort/FunctionalMergeSort.scala @@ -0,0 +1,30 @@ +package Sort + +object FunctionalMergeSort { + + /** @param vector + * - a vector of unsorted integers + * @return + * - vector of sorted integers @vector + */ + + @scala.annotation.tailrec + def merge(lh: Vector[Int], uh: Vector[Int], acc: Vector[Int] = Vector()): Vector[Int] = { + (lh, uh) match { + case (lhd +: ltl, uhd +: _) if lhd <= uhd => merge(ltl.toVector, uh, acc.appended(lhd)) + case (lhd +: _, uhd +: utl) if lhd > uhd => merge(lh, utl.toVector, acc.appended(uhd)) + case (Vector(), uh) => acc ++ uh + case _ => acc ++ lh + } + } + + def mergeSort(xs: Vector[Int]): Vector[Int] = { + if (xs.length <= 1) xs + else { + val m = xs.length / 2 + val (lh, uh) = xs.splitAt(m) + merge(mergeSort(lh), mergeSort(uh)) + } + } + +} diff --git a/src/test/scala/Sort/FunctionalMergeSortSpec.scala b/src/test/scala/Sort/FunctionalMergeSortSpec.scala new file mode 100644 index 0000000..3050880 --- /dev/null +++ b/src/test/scala/Sort/FunctionalMergeSortSpec.scala @@ -0,0 +1,12 @@ +package Sort + +import org.scalatest.flatspec.AnyFlatSpec + +class FunctionalMergeSortSpec extends AnyFlatSpec { + + "A Merge Sort" should "return a sorted version of a vector passed to it" in { + val vec = Vector(3, 2, 7, 1, 9, 0) + assert(FunctionalMergeSort.mergeSort(vec) === Vector(0, 1, 2, 3, 7, 9)) + } + +}