Stacks and Queues
Queue from Two Stacks
Implement queue behavior with an input stack and an output stack.
Algorithm
Basic Implementation
basic.kt
import java.util.ArrayDeque
fun render(values: List<Int>) = values.joinToString(" -> ")
fun main() {
val inStack = ArrayDeque<Int>()
val outStack = ArrayDeque<Int>()
for (value in listOf(10, 20, 30)) inStack.addLast(value)
while (!inStack.isEmpty()) outStack.addLast(inStack.removeLast())
val removed = mutableListOf<Int>()
while (!outStack.isEmpty()) removed.add(outStack.removeLast())
println(render(removed))
}
Complexity
- Time: O(1) amortized per operation
- Space: O(n)
Implementation notes
- Kotlin imports
java.util.ArrayDequeand createsval inStackandval outStackasArrayDeque<Int>instances. The bindings are not rebound, but both stack contents mutate. - Enqueue writes to the input stack with
inStack.addLast(value)forlistOf(10, 20, 30), producing[10, 20, 30]. - Transfer uses
while (!inStack.isEmpty()) outStack.addLast(inStack.removeLast()), moving values from the back ofinStackto the back ofoutStack. - Dequeue order comes from
outStack.removeLast()insidewhile (!outStack.isEmpty()), so the transferred stack yields10,20, then30. - The emptiness checks avoid the exception path for
removeLast()on an empty deque; values are non-nullInts throughout. - The trace shows
in=[]andout=[], thenin=[10, 20, 30], then transfer toin=[]andout=[30, 20, 10], then removed[10, 20, 30]. render(values: List<Int>)usesjoinToString(" -> "), andprintln(render(removed))prints10 -> 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.