Queue Implementation Using Array in DSA Rust - Time & Space Complexity
We want to understand how the time to add or remove items from a queue changes as the queue grows.
How does the queue's size affect the speed of its main operations?
Analyze the time complexity of the following code snippet.
struct Queue {
data: Vec<i32>,
front: usize,
rear: usize,
size: usize,
}
impl Queue {
fn enqueue(&mut self, val: i32) {
if self.rear < self.size {
self.data[self.rear] = val;
self.rear += 1;
}
}
fn dequeue(&mut self) -> Option<i32> {
if self.front == self.rear {
None
} else {
let val = self.data[self.front];
self.front += 1;
Some(val)
}
}
}
This code shows a queue using an array with front and rear pointers to add and remove items.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Adding or removing one item by moving front or rear index.
- How many times: Each enqueue or dequeue moves pointers once, no loops inside these methods.
Each enqueue or dequeue does a fixed number of steps regardless of queue size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 1 operation per enqueue or dequeue |
| 100 | 1 operation per enqueue or dequeue |
| 1000 | 1 operation per enqueue or dequeue |
Pattern observation: The time to add or remove an item stays the same no matter how big the queue is.
Time Complexity: O(1)
This means adding or removing an item takes the same short time no matter how many items are in the queue.
[X] Wrong: "Enqueue or dequeue takes longer as the queue grows because the array is bigger."
[OK] Correct: The code only moves pointers and accesses one position, so the size does not affect the time.
Understanding this constant time behavior shows you know how queues work efficiently, a key skill for many coding tasks.
"What if we used a linked list instead of an array? How would the time complexity of enqueue and dequeue change?"
Practice
Solution
Step 1: Understand queue behavior
A queue adds elements at the rear and removes from the front, so the first element added is the first removed.Step 2: Compare with options
This behavior matches FIFO, not LIFO or random access or sorting.Final Answer:
It follows First-In-First-Out (FIFO) order -> Option BQuick Check:
Queue = FIFO [OK]
- Confusing queue with stack (LIFO)
- Thinking queue allows random access
- Assuming queue sorts elements
Solution
Step 1: Identify Rust array syntax
In Rust, fixed-size arrays are declared as [type; size], and can be initialized with a repeated value like [0; 5].Step 2: Check options
let queue: [i32; 5] = [0; 5]; matches this syntax. let queue = Vec<i32>::new(5); uses Vec but with wrong new() usage. let queue: [i32] = [0, 0, 0, 0, 0]; misses size in type. let queue = [5]int{0}; is invalid Rust syntax.Final Answer:
let queue: [i32; 5] = [0; 5]; -> Option AQuick Check:
Rust array syntax = [type; size] [OK]
- Using Vec::new with size argument
- Missing size in array type
- Using non-Rust syntax like option D
let mut queue = [0; 3];
let mut front = 0;
let mut rear = 0;
// Enqueue 10
queue[rear] = 10;
rear += 1;
// Enqueue 20
queue[rear] = 20;
rear += 1;
// Dequeue
front += 1;
// Enqueue 30
queue[rear] = 30;
rear += 1;
println!("{:?}", &queue);
What is the printed output?Solution
Step 1: Trace enqueue and dequeue operations
Initially queue = [0,0,0], front=0, rear=0. Enqueue 10: queue[0]=10, rear=1 Enqueue 20: queue[1]=20, rear=2 Dequeue: front=1 (10 is logically removed but still in array) Enqueue 30: queue[2]=30, rear=3Step 2: Check final queue array
Array is [10, 20, 30]. Dequeue only moves front pointer, does not clear value.Final Answer:
[10, 20, 30] -> Option DQuick Check:
Array stores all enqueued values [OK]
- Assuming dequeue clears array slot
- Mixing front and rear indexes
- Confusing array content with logical queue content
let mut queue = [0; 3]; let mut front = 0; let mut rear = 0; // Enqueue 10 queue[rear] = 10; rear += 1; // Enqueue 20 queue[rear] = 20; rear += 1; // Enqueue 30 queue[rear] = 30; rear += 1; // Enqueue 40 queue[rear] = 40; rear += 1;
Solution
Step 1: Check array size and rear increments
Array size is 3, rear starts at 0 and increments after each enqueue. After enqueue 30, rear=3.Step 2: Enqueue 40 tries to access queue[3]
Index 3 is out of bounds for array of size 3, causing runtime error.Final Answer:
Index out of bounds error when enqueueing 40 -> Option CQuick Check:
Array size limit exceeded = error [OK]
- Ignoring array size limit
- Not checking rear before enqueue
- Misunderstanding pointer roles
enqueue(5) enqueue(10) enqueue(15) dequeue() enqueue(20) dequeue()What are the values of front and rear pointers, and the queue array content?
Solution
Step 1: Trace each operation with circular logic
Array size = 4, front=0, rear=0 initially. - enqueue(5): queue[0]=5, rear=(0+1)%4=1 - enqueue(10): queue[1]=10, rear=2 - enqueue(15): queue[2]=15, rear=3 - dequeue(): front=(0+1)%4=1 - enqueue(20): queue[3]=20, rear=(3+1)%4=0 - dequeue(): front=(1+1)%4=2Step 2: Final pointers and array
front=2, rear=0, queue = [5, 10, 15, 20]. Dequeue only moves front pointer, does not clear array values.Final Answer:
front = 2, rear = 0, queue = [5, 10, 15, 20] -> Option AQuick Check:
Circular queue pointers wrap with modulo [OK]
- Not using modulo for wrap-around
- Confusing front and rear updates
- Assuming dequeue clears array values
Ready to prove it?
Pass the test and this pattern moves unknown
