Created
November 2, 2016 17:14
-
-
Save george-hawkins/d107036ab9720e2711c7203cbd1a275f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sealed trait Conc[+T] { | |
def level: Int | |
def size: Int | |
def left: Conc[T] = throw new NoSuchElementException("no left subtree") | |
def right: Conc[T] = throw new NoSuchElementException("no right subtree") | |
def <>[U >: T](that: Conc[U]): Conc[U] = { | |
if (this == Empty) that | |
else if (that == Empty) this | |
else concat(this, that) | |
} | |
private def concat[U](xs: Conc[U], ys: Conc[U]): Conc[U] = { | |
val diff = ys.level - xs.level | |
if (math.abs(diff) <= 1) new <>(xs, ys) | |
else if (diff < -1) { // xs is more than one level taller. | |
if (xs.left.level >= xs.right.level) { | |
val nr = concat(xs.right, ys) | |
new <>(xs.left, nr) | |
} else { | |
val nrr = concat(xs.right.right, ys) | |
if (nrr.level == xs.level - 3) { | |
val nl = xs.left | |
val nr = new <>(xs.right.left, nrr) | |
new <>(nl, nr) | |
} else { | |
val nl = new <>(xs.left, xs.right.left) | |
val nr = nrr | |
new <>(nl, nr) | |
} | |
} | |
} else { // ys is more than one level taller. | |
??? | |
} | |
} | |
} | |
case object Empty extends Conc[Nothing] { | |
def level = 0 | |
def size = 0 | |
} | |
class Single[T](val x: T) extends Conc[T] { | |
def level = 0 | |
def size = 1 | |
} | |
case class <>[T](override val left: Conc[T], override val right: Conc[T]) extends Conc[T] { | |
val level = 1 + math.max(left.level, right.level) | |
val size = left.size + right.size | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment