All Downloads are FREE. Search and download functionalities are using the official Maven repository.

hael.jjm-core_2.13.0.2.3.source-code.TarjanUnionFind.scala Maven / Gradle / Ivy

The newest version!
package jjm

import scala.collection.mutable

import cats.implicits._

/** Efficient mutable union-find data structure
  * using union-by-rank and path compression. */
class TarjanUnionFind[A] private (
  cells: mutable.Map[A, TarjanUnionFind.UFCell[A]]
) {
  import TarjanUnionFind._

  def add(a: A): Unit = {
    if(!cells.contains(a)) cells.put(a, new UFCell(a))
  }

  def find(a: A): Option[A] = {
    findCell(a).map(_.value)
  }
  private[this] def findCell(a: A): Option[UFCell[A]] = {
    this.cells.get(a).map(ufA => findCellAux(ufA, Nil))
  }
  private[this] def findCellAux(a: UFCell[A], prevCells: List[UFCell[A]]): UFCell[A] = {
    // path compression
    if(a.parent == a) {
      prevCells.foreach(_.parent = a)
      a
    } else {
      findCellAux(a.parent, a :: prevCells)
    }
  }

  def union(a: A, b: A): Option[A] = {
    (findCell(a), findCell(b)).mapN { (x, y) =>
      // union-by-rank
      if(x.rank < y.rank) {
        x.parent = y
        y.value
      } else if(y.rank < x.rank) {
        y.parent = x
        x.value
      } else {
        x.parent = y
        y.rank = y.rank + 1
        y.value
      }
    }
  }
}
object TarjanUnionFind {
  private class UFCell[A](val value: A) {
    var parent: UFCell[A] = this
    var rank: Int = 0
  }
  def empty[A] = new TarjanUnionFind(mutable.Map.empty[A, UFCell[A]])
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy