Stacks and Queues
Queue from Two Stacks
Implement queue behavior with an input stack and an output stack.
Algorithm
Basic Implementation
basic.scala
def render(values: Seq[Int]): String = values.mkString(" -> ")
var inStack = List[Int]()
var outStack = List[Int]()
for (value <- List(10, 20, 30)) inStack = value :: inStack
while (inStack.nonEmpty) { outStack = inStack.head :: outStack; inStack = inStack.tail }
var removed = List[Int]()
while (outStack.nonEmpty) { removed = removed :+ outStack.head; outStack = outStack.tail }
println(render(removed))
Complexity
- Time: O(1) amortized per operation
- Space: O(n)
Implementation notes
- This checked source uses top-level Scala code with
List[Int]values as the two stacks, not a queue class. var inStack = List[Int]()andvar outStack = List[Int]()are mutable bindings; each reassignment points the variable at a new list.- Enqueue uses
inStack = value :: inStack, so each new value is pushed onto the front of the input stack's underlyingList; after enqueue, the raw Scala list head order isList(30, 20, 10). - The transfer loop is guarded by
while (inStack.nonEmpty), then movesinStack.headtooutStackwithoutStack = inStack.head :: outStackand advances input withinStack = inStack.tail. - Because
headandtailare only used afternonEmpty, this source has noOptionreturn or sentinel path for empty stacks. - The trace presents queued values as
[10, 20, 30]and the transferred stack asoutStack = [30, 20, 10]; that is a logical stack display, not ScalaListiteration order. - After transfer, the raw Scala
outStackhead order isList(10, 20, 30), soremoved = removed :+ outStack.headrecords10, then20, then30beforeoutStack = outStack.taildrains it. render(values: Seq[Int])usesmkString(" -> "), soprintln(render(removed))writes10 -> 20 -> 30.
input stack
Enqueue pushes new values onto the input stack.
output stack
When the output stack is empty, transferring all input values reverses them into dequeue order.