我们可以简单地使用ArrayList在java中实现一个队列,但是在Scala Lists的情况下,列表是不可变的,所以如何使用Scala中的List实现队列。有人给我一些提示。
答案 0 :(得分:4)
这是来自Scala的immutable Queue:
队列实现为一对列表,一个包含in元素,另一个包含out元素。元素将添加到列表中,并从列表中删除。当out列表运行干掉时,通过用in.reverse替换out列表来轮换队列,并用Nil替换。
所以:
object Queue {
def empty[A]: Queue[A] = new Queue(Nil, Nil)
}
class Queue[A] private (in: List[A], out: List[A]) {
def isEmpty: Boolean = in.isEmpty && out.isEmpty
def push(elem: A): Queue[A] = new Queue(elem :: in, out)
def pop(): (A, Queue[A]) =
out match {
case head :: tail => (head, new Queue(in, tail))
case Nil =>
val head :: tail = in.reverse // throws exception if empty
(head, new Queue(Nil, tail))
}
}
var q = Queue.empty[Int]
(1 to 10).foreach(i => q = q.push(i))
while (!q.isEmpty) { val (i, r) = q.pop(); println(i); q = r }
答案 1 :(得分:0)
如果我们谈论mutable
列表,由于以下原因,它们不是实现队列的有效结构:将元素添加到列表的开头非常有效(使常量时间),但最终弹出元素根本不高效(列表中的元素越多,花费的时间越长)。
另请注意,Scala已经有一个Queue类:scala.collection.mutable.Queue
。
使用immutable
列表实现队列的唯一方法是使用var
。祝你好运!
答案 2 :(得分:0)
使用不可变列表,您必须在任何修改操作后返回新的List。一旦你掌握了它,它就会很简单。 Queue也是不可变的最小(但效率低下)实现可能是:
class Queue[T](content:List[T]) {
def pop() = new Queue(content.init)
def push(element:T) = new Queue(element::content)
def peek() = content.last
override def toString() = "Queue of:" + content.toString
}
val q= new Queue(List(1)) //> q : lists.queue.Queue[Int] = Queue of:List(1)
val r = q.push(2) //> r : lists.queue.Queue[Int] = Queue of:List(2, 1)
val s = r.peek() //> s : Int = 1
val t = r.pop() //> t : lists.queue.Queue[Int] = Queue of:List(2)