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 Rust 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.rs
use std::collections::VecDeque;
fn render(values: &[i32]) -> String {
values.iter().map(|v| v.to_string()).collect::<Vec<_>>().join(" -> ")
}
fn main() {
let mut in_stack = Vec::new();
let mut out_stack = Vec::new();
for value in [10, 20, 30] { in_stack.push(value); }
while let Some(value) = in_stack.pop() { out_stack.push(value); }
let mut removed = Vec::new();
while let Some(value) = out_stack.pop() { removed.push(value); }
println!("{}", render(&removed));
}
Complexity
- Time: O(1) amortized per operation
- Space: O(n)
Implementation notes
- The checked source imports
VecDeque, but the actual queue uses two mutableVec<i32>stacks:in_stackfor enqueues andout_stackfor dequeues. - Enqueue pushes owned
i32values from[10, 20, 30]within_stack.push(value), producing[10, 20, 30]. - Transfer uses
while let Some(value) = in_stack.pop() { out_stack.push(value); }.Vec::popreturnsOption<i32>;Some(value)moves the integer from the input stack to the output stack, andNoneends the loop. - Because stack pop removes from the end, the transfer reverses order into
out_stack=[30, 20, 10], putting10at the output stack's top. - Dequeue drains
out_stackwith anotherwhile let Some(value) = out_stack.pop()loop and pushes intoremoved, yielding[10, 20, 30]. - The trace records empty stacks, enqueue to
in=[10, 20, 30], transfer toout=[30, 20, 10], then FIFO removal without=[]. render(&removed)borrows the result slice, converts each value withto_string(), joins with" -> ", andprintln!("{}", ...)prints10 -> 20 -> 30.