Queue vs Stack When to Use Which in DSA Rust - Complexity Comparison
We want to understand how fast operations happen in queues and stacks.
Which one is better for different tasks and why?
Analyze the time complexity of the following code snippet.
struct Stack {
elements: Vec<i32>,
}
impl Stack {
fn push(&mut self, val: i32) {
self.elements.push(val);
}
fn pop(&mut self) -> Option<i32> {
self.elements.pop()
}
}
struct Queue {
elements: Vec<i32>,
}
impl Queue {
fn enqueue(&mut self, val: i32) {
self.elements.push(val);
}
fn dequeue(&mut self) -> Option<i32> {
if self.elements.is_empty() {
None
} else {
Some(self.elements.remove(0))
}
}
}
This code shows simple stack and queue operations using a vector.
Look at the main repeated actions in each data structure.
- Primary operation: Stack uses push and pop at the end of the vector.
- How many times: Each push or pop happens once per operation.
- Primary operation: Queue uses enqueue at the end and dequeue by removing the first element.
- How many times: Each enqueue is once, but dequeue removes the first element causing all others to shift.
Stack operations stay fast no matter how big the data is.
Queue dequeue gets slower as more items are inside because it shifts elements.
| Input Size (n) | Stack push/pop Operations | Queue dequeue Operations |
|---|---|---|
| 10 | 10 simple steps | 10 steps with small shifts |
| 100 | 100 simple steps | 100 steps with bigger shifts |
| 1000 | 1000 simple steps | 1000 steps with large shifts |
Pattern observation: Stack operations take the same time each call, queue dequeue time grows with size.
Time Complexity: O(1) for Stack push/pop, O(n) for Queue dequeue
Stack operations are always quick; queue dequeue gets slower as more items are inside.
[X] Wrong: "Queue dequeue is always as fast as stack pop because both remove one item."
[OK] Correct: Queue dequeue removes the first item, causing all other items to move, which takes more time as the queue grows.
Knowing when stack or queue operations are fast helps you pick the right tool for the job.
This skill shows you understand how data structures work under the hood, a key part of problem solving.
"What if we used a linked list instead of a vector for the queue? How would the time complexity change?"
Practice
Solution
Step 1: Understand the order requirement
Processing items in the exact order they arrive means first-in, first-out (FIFO).Step 2: Match order to data structure
Queue follows FIFO, so it fits the requirement perfectly.Final Answer:
Queue -> Option AQuick Check:
FIFO = Queue [OK]
- Choosing stack which is last-in, first-out
- Confusing queue with other data structures
- Ignoring the order requirement
Solution
Step 1: Recall Rust vector creation syntax
In Rust, Vec::new() creates an empty vector.Step 2: Check mutability and type annotation
Stack needs to be mutable to push/pop, and type must be specified or inferred.Final Answer:
let mut stack: Vec<i32> = Vec::new(); -> Option AQuick Check:
Vec::new() creates empty vector [OK]
- Using Vec::empty() which does not exist
- Using new keyword like other languages
- Missing mut keyword for modification
let mut stack = Vec::new();
stack.push(10);
stack.push(20);
stack.push(30);
while let Some(top) = stack.pop() {
print!("{} ", top);
}Solution
Step 1: Understand stack push order
Items pushed: 10, then 20, then 30. Stack top is 30.Step 2: Pop items prints in last-in, first-out order
Pop removes 30 first, then 20, then 10, printing "30 20 10 ".Final Answer:
30 20 10 -> Option CQuick Check:
LIFO order = 30 20 10 [OK]
- Assuming FIFO order for stack
- Confusing push and pop order
- Expecting compilation error
let mut queue = Vec::new();
queue.push(1);
queue.push(2);
queue.remove(0);
queue.remove(0);
println!("{:?}", queue);Solution
Step 1: Understand vector remove(0) behavior
remove(0) deletes first element but shifts all others left, costly for large vectors.Step 2: Identify inefficiency in queue implementation
Repeated remove(0) causes O(n) shifts, making it inefficient for queues.Final Answer:
Using remove(0) is inefficient for large queues -> Option BQuick Check:
remove(0) shifts elements = inefficient [OK]
- Thinking remove(0) causes error
- Assuming push() does not add elements
- Ignoring performance impact
Solution
Step 1: Understand processing order requirement
Tasks must be processed in arrival order, so a queue (FIFO) is needed.Step 2: Understand undo requirement
Undo last task quickly means last-in, first-out order, so a stack fits undo.Step 3: Combine data structures
Use queue for normal processing and stack to track tasks for undo.Final Answer:
Use a queue for tasks and a stack for undo operations -> Option DQuick Check:
Queue for order + Stack for undo = Use a queue for tasks and a stack for undo operations [OK]
- Using only stack loses arrival order
- Using only queue cannot undo last task easily
- Choosing HashMap which doesn't preserve order
Ready to prove it?
Pass the test and this pattern moves unknown
