Advertisement
Cool_Dalek

PriorityStack

Feb 11th, 2022 (edited)
989
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 2.57 KB | None | 0 0
  1. import scala.collection.mutable
  2.  
  3. trait PriorityStack[Elem] {
  4.  
  5.   def pop(): Option[Elem]
  6.  
  7.   def push(elem: Elem): Unit
  8.  
  9. }
  10. object PriorityStack {
  11.  
  12.   private class Impl[Elem: Ordering](
  13.                                       initialCapacity: Int,
  14.                                       capacityFactor: Float,
  15.                                     ) extends PriorityStack[Elem] {
  16.  
  17.     private val ordering: Ordering[AnyRef] = new Ordering[AnyRef] {
  18.       override def compare(x: AnyRef, y: AnyRef): Int =
  19.         (x, y) match {
  20.           case (null, _) => 1
  21.           case (_, null) => -1
  22.           case (null, null) => 0
  23.           case _ => Ordering[Elem].compare(
  24.             x.asInstanceOf[Elem],
  25.             y.asInstanceOf[Elem],
  26.           )
  27.         }
  28.     }
  29.  
  30.     private var underlying = new Array[AnyRef](initialCapacity)
  31.  
  32.     private var last = -1
  33.  
  34.     override def pop(): Option[Elem] =
  35.       if(last > 0) {
  36.  
  37.         def shrink(): Unit = {
  38.           val needShrink = (last * capacityFactor).toInt < underlying.length
  39.           if (needShrink) {
  40.             val shrinked = new Array[AnyRef](last)
  41.             Array.copy(
  42.               src = underlying,
  43.               srcPos = 0,
  44.               dest = shrinked,
  45.               destPos = 0,
  46.               length = last,
  47.             )
  48.           }
  49.         }
  50.  
  51.         def head(): Option[Elem] = {
  52.           val take = last
  53.           last -= 1
  54.           val elem = underlying(take).asInstanceOf[Elem]
  55.           underlying(take) = null.asInstanceOf[AnyRef]
  56.           Some(elem)
  57.         }
  58.  
  59.         shrink()
  60.         head()
  61.       } else {
  62.         None
  63.       }
  64.  
  65.     override def push(elem: Elem): Unit = {
  66.  
  67.       def grow(): Unit = {
  68.         val current = last + 1
  69.         if(current > underlying.length) {
  70.           val size = (current * capacityFactor).toInt
  71.           val growed = new Array[AnyRef](size)
  72.           Array.copy(
  73.             src = underlying,
  74.             srcPos = 0,
  75.             dest = growed,
  76.             destPos = 0,
  77.             length = last,
  78.           )
  79.           underlying = growed
  80.         }
  81.         last = current
  82.       }
  83.  
  84.       def insert(): Unit = {
  85.         underlying(last) = elem.asInstanceOf[AnyRef]
  86.         underlying.sortInPlace()(ordering)
  87.       }
  88.  
  89.       grow()
  90.       insert()
  91.     }
  92.  
  93.     override def toString(): String =
  94.       underlying.mkString("PriorityStack(", ", ", ")")
  95.  
  96.   }
  97.  
  98.   def apply[Elem: Ordering](initialCapacity: Int = 16,
  99.                             growFactor: Float = 2f): PriorityStack[Elem] =
  100.     new Impl[Elem](initialCapacity, growFactor)
  101.  
  102. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement