Consider a queue implemented using a fixed-size array of length 5. Initially, the queue is empty. The following operations are performed in order:
- enqueue(10)
- enqueue(20)
- enqueue(30)
- dequeue()
- enqueue(40)
- dequeue()
What is the state of the queue after these operations?
struct Queue {
arr: [i32; 5],
front: usize,
rear: usize,
size: usize,
}
impl Queue {
fn new() -> Self {
Queue { arr: [0; 5], front: 0, rear: 0, size: 0 }
}
fn enqueue(&mut self, val: i32) {
if self.size == 5 { return; }
self.arr[self.rear] = val;
self.rear = (self.rear + 1) % 5;
self.size += 1;
}
fn dequeue(&mut self) -> Option<i32> {
if self.size == 0 { return None; }
let val = self.arr[self.front];
self.front = (self.front + 1) % 5;
self.size -= 1;
Some(val)
}
fn print_queue(&self) {
let mut i = self.front;
let mut count = self.size;
while count > 0 {
print!("{} -> ", self.arr[i]);
i = (i + 1) % 5;
count -= 1;
}
print!("null\n");
}
}
fn main() {
let mut q = Queue::new();
q.enqueue(10);
q.enqueue(20);
q.enqueue(30);
q.dequeue();
q.enqueue(40);
q.dequeue();
q.print_queue();
}Remember that dequeue removes from the front and enqueue adds at the rear. The queue uses circular indexing.
After enqueue(10), enqueue(20), enqueue(30), the queue is: 10 -> 20 -> 30 -> null
dequeue() removes 10, queue becomes: 20 -> 30 -> null
enqueue(40) adds 40 at rear: 20 -> 30 -> 40 -> null
dequeue() removes 20, queue becomes: 30 -> 40 -> null
Since the queue uses circular indexing, the front points to index 2 (30), so the print_queue outputs 30 -> 40 -> null.
Given a queue implemented with a fixed-size array of length 3, initially empty. The following operations are performed:
- enqueue(1)
- enqueue(2)
- enqueue(3)
- enqueue(4)
What happens when enqueue(4) is called?
struct Queue {
arr: [i32; 3],
front: usize,
rear: usize,
size: usize,
}
impl Queue {
fn new() -> Self {
Queue { arr: [0; 3], front: 0, rear: 0, size: 0 }
}
fn enqueue(&mut self, val: i32) {
if self.size == 3 {
panic!("Queue is full");
}
self.arr[self.rear] = val;
self.rear = (self.rear + 1) % 3;
self.size += 1;
}
}
fn main() {
let mut q = Queue::new();
q.enqueue(1);
q.enqueue(2);
q.enqueue(3);
q.enqueue(4);
}Check the condition before adding a new element to the queue.
The enqueue method checks if the queue size equals the array length (3). If full, it panics with "Queue is full". So enqueue(4) causes a panic.
Consider this dequeue method for a queue implemented with a fixed-size array and circular indexing:
fn dequeue(&mut self) -> Option{ if self.size == 0 { return None; } let val = self.arr[self.front]; self.front += 1; self.size -= 1; Some(val) }
What is the bug in this code?
fn dequeue(&mut self) -> Option<i32> {
if self.size == 0 {
return None;
}
let val = self.arr[self.front];
self.front += 1;
self.size -= 1;
Some(val)
}Remember the queue uses circular indexing for front and rear.
The front index is incremented without modulo operation, so after reaching the array end, it goes out of bounds causing runtime error.
Why is circular indexing used in array-based queue implementations?
Think about what happens when elements are dequeued from the front.
Without circular indexing, after dequeuing elements, the front moves forward and the space at the start of the array is wasted. Circular indexing allows the rear to wrap around and reuse that space.
Given a circular queue of size 4, initially empty, perform these operations:
- enqueue(5)
- enqueue(10)
- enqueue(15)
- dequeue()
- enqueue(20)
- enqueue(25)
- dequeue()
- enqueue(30)
What is the final printed state of the queue?
struct Queue {
arr: [i32; 4],
front: usize,
rear: usize,
size: usize,
}
impl Queue {
fn new() -> Self {
Queue { arr: [0; 4], front: 0, rear: 0, size: 0 }
}
fn enqueue(&mut self, val: i32) {
if self.size == 4 { return; }
self.arr[self.rear] = val;
self.rear = (self.rear + 1) % 4;
self.size += 1;
}
fn dequeue(&mut self) -> Option<i32> {
if self.size == 0 { return None; }
let val = self.arr[self.front];
self.front = (self.front + 1) % 4;
self.size -= 1;
Some(val)
}
fn print_queue(&self) {
let mut i = self.front;
let mut count = self.size;
while count > 0 {
print!("{} -> ", self.arr[i]);
i = (i + 1) % 4;
count -= 1;
}
print!("null\n");
}
}
fn main() {
let mut q = Queue::new();
q.enqueue(5);
q.enqueue(10);
q.enqueue(15);
q.dequeue();
q.enqueue(20);
q.enqueue(25);
q.dequeue();
q.enqueue(30);
q.print_queue();
}Track front and rear indices carefully after each operation with modulo wrapping.
Operations step-by-step:
- enqueue(5): queue = 5
- enqueue(10): queue = 5,10
- enqueue(15): queue = 5,10,15
- dequeue(): removes 5, queue = 10,15
- enqueue(20): queue = 10,15,20
- enqueue(25): queue = 10,15,20,25 (full)
- dequeue(): removes 10, queue = 15,20,25
- enqueue(30): queue = 15,20,25,30 (full)
Final queue elements in order: 15 -> 20 -> 25 -> 30 -> null
