Skip to content

Instantly share code, notes, and snippets.

@baseerhk
Last active November 8, 2019 09:05
Show Gist options
  • Save baseerhk/9c5a614696cc9f0478ebfc69fec009be to your computer and use it in GitHub Desktop.
Save baseerhk/9c5a614696cc9f0478ebfc69fec009be to your computer and use it in GitHub Desktop.
Complete binary tree Scala implementation
sealed trait CompleteBinaryTree[A] {
def lookup(size: Int, index: Int): A = (this, index) match {
case (Leaf(x), 0) => x
case (Leaf(_), _) => throw new Exception("Index is not in list.")
case (Node(x, _, _), 0) => x
case (Node(x, l, _), i) if i <= size / 2 => l.lookup(size / 2, i - 1)
case (Node(x, _, r), i) if i > size / 2 => r.lookup(size / 2, i - 1 - size / 2)
}
def update(size: Int, index: Int, y: A): CompleteBinaryTree[A] = (this, index) match {
case (Leaf(_), 0) => Leaf(y)
case (Leaf(_), _) => throw new Exception("Index is not in list.")
case (Node(_, l, r), 0) => Node(y, l, r)
case (Node(x, l, r), i) if i <= size / 2 => Node(x, l.update(size / 2, i - 1, y), r)
case (Node(x, l, r), i) if i > size / 2 => Node(x, l, r.update(size / 2, i - 1 - size / 2, y))
}
}
object CompleteBinaryTree {
def apply[A](xs: List[A]): CompleteBinaryTree[A] = {
def inner(xs: List[A], size: Int): CompleteBinaryTree[A] = size match {
case 1 => Leaf(xs.head)
case s if Math.pow(2, Math.floor(Math.log(s + 1)/ Math.log(2))).toInt == s + 1 => {
val t = xs.tail
val s_ = size / 2
Node(xs.head, inner(t.take(s_), s_), inner(t.drop(s_), s_))
}
case _ => throw new Exception("Size is not a skew binary.")
}
inner(xs, xs.length)
}
}
case class Leaf[A](value: A) extends CompleteBinaryTree[A]
case class Node[A](value: A, l: CompleteBinaryTree[A], r: CompleteBinaryTree[A]) extends CompleteBinaryTree[A]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment