priorityqueue.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 197 行
SCALA
197 行
/* __ *\** ________ ___ / / ___ Scala API **** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **** /____/\___/_/ |_/____/_/ | | **** |/ **\* */// $Id: PriorityQueue.scala 12404 2007-07-24 17:43:47Z odersky $package scala.collection.mutable//import Predef.{NoSuchElementException, UnsupportedOperationException}/** This class implements priority queues using a heap. The * elements of the queue have to be ordered in terms of the * <code>Ordered[T]</code> class. * * @author Matthias Zenger * @version 1.0, 03/05/2004 */@serializable @cloneableclass PriorityQueue[A <% Ordered[A]] extends ResizableArray[A] with CloneableCollection { size0 = size0 + 1 // we do not use array(0) protected def fixUp(as: Array[A], m: Int): Unit = { var k: Int = m while ((k > 1) && (as(k / 2) < as(k))) { swap(k, k / 2) k = k / 2 } } protected def fixDown(as: Array[A], m: Int, n: Int): Unit = { var k: Int = m var loop: Boolean = true while (loop && (n >= 2 * k)) { var j = 2 * k if ((j < n) && (as(j) < as(j + 1))) j = j + 1; if (!(as(k) < as(j))) loop = false else { val h = as(k) as(k) = as(j) as(j) = h k = j } } } /** Checks if the queue is empty. * * @return true, iff there is no element in the queue. */ override def isEmpty: Boolean = size0 < 2 /** Inserts a single element into the priority queue. * * @param elem the element to insert */ def +=(elem: A): Unit = { ensureSize(size0+1) array(size0) = elem fixUp(array, size0) size0 = size0 + 1 } def +(elem: A): PriorityQueue[A] = { this += elem; this } /** Add two or more elements to this set. * @param elem1 the first element. * @param kv2 the second element. * @param kvs the remaining elements. */ def += (elem1: A, elem2: A, elems: A*) { this += elem1; this += elem2; this ++= elems } def + (elem1: A, elem2: A, elems: A*) = { this.+=(elem1, elem2, elems: _*); this } /** Adds all elements provided by an <code>Iterable</code> object * into the priority queue. * * @param iter an iterable object */ def ++=(iter: Iterable[A]): Unit = this ++= iter.elements /** Adds all elements provided by an iterator into the priority queue. * * @param it an iterator */ def ++=(it: Iterator[A]): Unit = it foreach { e => this += e } def ++(iter: Iterable[A]): PriorityQueue[A] = { this ++= iter; this } def ++(iter: Iterator[A]): PriorityQueue[A] = { this ++= iter; this } /** Adds all elements to the queue. * * @param elems the elements to add. */ def enqueue(elems: A*): Unit = (this ++= elems) /** Returns the element with the highest priority in the queue, * and removes this element from the queue. * * @throws Predef.NoSuchElementException * @return the element with the highest priority. */ def dequeue(): A = if (size0 > 1) { size0 = size0 - 1 swap(1, size0) fixDown(array, 1, size0 - 1) array(size0) } else throw new NoSuchElementException("no element to remove from heap") /** Returns the element with the highest priority in the queue, * or throws an error if there is no element contained in the queue. * * @return the element with the highest priority. */ def max: A = if (size0 > 1) array(1) else throw new NoSuchElementException("queue is empty") /** Removes all elements from the queue. After this operation is completed, * the queue will be empty. */ def clear(): Unit = { size0 = 1 } /** Returns an iterator which yiels all the elements of the priority * queue in descending priority order. * * @return an iterator over all elements sorted in descending order. */ override def elements: Iterator[A] = new Iterator[A] { val as: Array[A] = new Array[A](size0) Array.copy(array, 0, as, 0, size0) var i = size0 - 1 def hasNext: Boolean = i > 0 def next(): A = { val res = as(1) as(1) = as(i) i = i - 1 fixDown(as, 1, i) res } } /** Checks if two queues are structurally identical. * * @return true, iff both queues contain the same sequence of elements. */ override def equals(obj: Any): Boolean = obj match { case that: PriorityQueue[_] => (this.elements zip that.elements) forall { case (thiselem, thatelem) => thiselem == thatelem } case _ => false } /** The hashCode method always yields an error, since it is not * safe to use mutable queues as keys in hash tables. * * @return never. */ override def hashCode(): Int = throw new UnsupportedOperationException("unsuitable as hash key") /** Returns a regular queue containing the same elements. */ def toQueue: Queue[A] = { val res = new Queue[A] res ++= this res } /** Returns a textual representation of a queue as a string. * * @return the string representation of this queue. */ override def toString() = toList.mkString("PriorityQueue(", ", ", ")") /** This method clones the priority queue. * * @return a priority queue with the same elements. */ override def clone(): PriorityQueue[A] = { val res = new PriorityQueue[A] res ++= this res }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?