🦸♂️ Coding Interview Hero 🦸♀️
Sorting algorithms
Exercice: implement the bubble sort of a List[A]
with A
a generic type using tail recursion.
import scala.annotation.tailrec
class BubbleSort[A] (implicit ev: A => Ordered[A]) {
def sort(list: List[A]): List[A] = {
@tailrec
def sortRec(iteration: List[A], source: List[A], result: List[A]) : List[A]= source match {
case h1 :: h2 :: rest => if(ev(h1) > h2) sortRec(iteration, h1 :: rest, result :+ h2) else sortRec(iteration, h2 :: rest, result :+ h1)
case l:: Nil => sortRec(iteration, Nil, result :+ l)
case Nil => if(iteration.isEmpty) result else sortRec(iteration.dropRight(1), result, Nil )
}
sortRec(list, list, Nil)
}
}
Question: what is the time complexity? $$ T_n = O(n^2) $$
Exercice: implement the merge sort of a List[A]
with A
a generic type using tail recursion.
import scala.annotation.tailrec
class MergeSort[A](implicit ev: A => Ordered[A]) {
def sort(list: List[A]): List[A] = {
val m = list.length / 2
if (m == 0) list
else {
@tailrec
def merge(ls: List[A], rs: List[A], acc: List[A] = List()): List[A] = (ls, rs) match {
case (Nil, _) => acc ++ rs
case (_, Nil) => acc ++ ls
case (l :: ls1, r :: rs1) =>
if (ev(l) < r) merge(ls1, rs, acc :+ l)
else merge(ls, rs1, acc :+ r)
}
val (l, r) = list splitAt m
merge(sort(l), sort(r))
}
}
}
Question: what is the time complexity? $$ T_n = O(n\times log(n)) $$
Then running a JMH benchmark will produce such output:
Benchmark |
Mode |
Threads |
Samples |
Score |
Score Error (99,9%) |
Unit |
sort.SortBenchmark.BubbleSort |
thrpt |
1 |
4 |
329,785133 |
128,285418 |
ops/s |
sort.SortBenchmark.MergeSort |
thrpt |
1 |
4 |
14395,874073 |
5231,756727 |
ops/s |
All code is available on github.