diff --git a/src/main/scala/Sort/functional/MergeSort.scala b/src/main/scala/Sort/functional/MergeSort.scala new file mode 100644 index 0000000..fe9f2a4 --- /dev/null +++ b/src/main/scala/Sort/functional/MergeSort.scala @@ -0,0 +1,47 @@ +package Sort.functional + +object MergeSort { + + /* + * The concept behind merge sort is very simple. + * Keep splitting the array into halves until the subarrays hit a size of one, sort them, and merge the sorted arrays, + * which will result in an ultimate sorted array. Y + * ou might have figured out that this sounds exactly like the fibonacci sequence using recursion, and you would be right! + * We can, and will be using recursion to perform this. + * Worst case - Big O(nlogn) + * */ + + // A function to merge two sorted lists + def merge(xs: List[Int], ys: List[Int]): List[Int] = (xs, ys) match { + + // If either list is empty, return the other list + case (Nil, _) => ys + case (_, Nil) => xs + + // If the first element of xs is smaller than the first element of ys, + // append it to the result of merging the rest of xs with ys + case (x :: xtail, y :: ytail) => + if (x < y) x :: merge(xtail, ys) + // Otherwise, append the first element of ys to the result of merging xs with the rest of ys + else y :: merge(xs, ytail) + } + + // A function to sort a list using merge sort + def mergeSort(xs: List[Int]): List[Int] = { + + // Find the middle index of the list + val n = xs.length / 2 + + // If the list has less than two elements, it is already sorted + if (n == 0) xs + else { + + // Split the list into two sublists + val (left, right) = xs.splitAt(n) + + // Sort each sublist recursively and merge them + merge(mergeSort(left), mergeSort(right)) + } + } + +} diff --git a/src/main/scala/Sort/functional/QuickSort.scala b/src/main/scala/Sort/functional/QuickSort.scala new file mode 100644 index 0000000..64ed221 --- /dev/null +++ b/src/main/scala/Sort/functional/QuickSort.scala @@ -0,0 +1,20 @@ +package Sort.functional + +object QuickSort { + def quickSort(arr: List[Int]): List[Int] = { + // Base case: empty or singleton list is already sorted + if (arr.length <= 1) { + return arr + } + + // Choose the first element as the pivot + val pivot = arr.head + + // Partition the list into two sublists: + // elements smaller than or equal to pivot, and elements greater than pivot + val (smaller, greater) = arr.tail.partition(_ <= pivot) + + // Recursively sort the sublists and concatenate them with the pivot + quickSort(smaller) ::: pivot :: quickSort(greater) + } +} \ No newline at end of file diff --git a/src/test/scala/Sort/functional/MergeSortSpec.scala b/src/test/scala/Sort/functional/MergeSortSpec.scala new file mode 100644 index 0000000..ac49352 --- /dev/null +++ b/src/test/scala/Sort/functional/MergeSortSpec.scala @@ -0,0 +1,11 @@ +package Sort.functional + +import org.scalatest.flatspec.AnyFlatSpec + +class MergeSortSpec extends AnyFlatSpec { + + "A Functional Merge Sort" should "return a sorted version of a List passed to it" in { + assert(MergeSort.mergeSort(List(8,3,6,1,5,9,6,2)) === List(1,2,3,5,6,6,8,9)) + } + +} diff --git a/src/test/scala/Sort/functional/QuickSortSpec.scala b/src/test/scala/Sort/functional/QuickSortSpec.scala new file mode 100644 index 0000000..f5b43bf --- /dev/null +++ b/src/test/scala/Sort/functional/QuickSortSpec.scala @@ -0,0 +1,11 @@ +package Sort.functional + +import org.scalatest.flatspec.AnyFlatSpec + +class QuickSortSpec extends AnyFlatSpec { + + "A Functional Quick Sort" should "return a sorted version of a List passed to it" in { + assert(QuickSort.quickSort(List(6,2,4,1,3)) === List(1,2,3,4,6)) + } + +}