Problem Description
Design a circular queue that supports the following operations: enQueue, deQueue, Front, Rear, isEmpty, and isFull. The circular queue should efficiently reuse empty spaces and maintain a FIFO (first in, first out) logic. The challenge is to implement these operations without using the built-in queue data structure.
Key Insights
- Leverage a fixed-size array to store the queue elements.
- Use two pointers: one for the front and one for the rear.
- Maintain a count variable (or use pointer arithmetic) to differentiate between an empty and a full queue.
- Use modulo arithmetic to wrap pointers when they reach the end of the array.
- Ensure all operations (enQueue, deQueue, Front, Rear, isEmpty, isFull) have O(1) time complexity.
Space and Time Complexity
Time Complexity: O(1) per operation for enQueue, deQueue, Front, Rear, isEmpty, and isFull. Space Complexity: O(k), where k is the capacity of the circular queue.
Solution
We implement the circular queue using a fixed-size array alongside two pointers, front and rear, and a counter to keep track of the number of elements in the queue. The front pointer indicates the index of the first element, and the rear pointer indicates the index where the next element will be enqueued. When enqueuing an element, we insert the element at the rear index and then increment the rear pointer modulo the size of the array. Similarly, when dequeuing, we remove the element at the front index and increment the front pointer modulo the size. The counter helps in quickly checking if the queue is empty or full (count equals 0 or count equals capacity, respectively). This design ensures all operations remain O(1) and correctly wraps around, forming a circular structure.