Stacks and Queues
Queue from Two Stacks
Implement queue behavior with an input stack and an output stack.
Algorithm
The replay uses the same three values in every language, so this Scala DSA implementation can be compared directly with the rest of the DSA track.
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.
Visual walkthrough
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.