Data Structures & AlgorithmsMedium
Let's implement a circular queue in Java. A circular queue, also known as a ring buffer, is a fixed-size data structure that operates as if the end is connected to the beginning. This is particularly useful in scenarios where you want to maintain a history of the most recent 'n' elements, such as in real-time data processing or managing tasks in an operating system. Your implementation should include the following functionalities: Initialization: The queue should be initialized with a specified capacity. Enqueue (Insertion): Add an element to the rear of the queue. If the queue is full, the insertion should fail, and an appropriate message should be returned. Dequeue (Deletion): Remove an element from the front of the queue. If the queue is empty, the deletion should fail, and an appropriate message should be returned. Peek: Return the element at the front of the queue without removing it. Return null if the queue is empty. isEmpty: Check if the queue is empty. isFull: Check if the queue is full. Size: Return the current number of elements in the queue. Print Queue: Implement a method to print the current elements in the queue. This is useful for debugging and visualization. For example, if the queue has a capacity of 5, and you enqueue elements 1, 2, 3, 4, and 5, the queue is full. If you then dequeue one element, the element 1 is removed, and you can enqueue a new element, say 6. The queue now contains 2, 3, 4, 5, and 6. Make sure your implementation handles the circular nature correctly, meaning the rear pointer should wrap around to the beginning of the array when it reaches the end, and the front pointer should wrap around similarly when dequeuing. Provide a complete, runnable Java code solution with comments to explain the logic behind each method. Also include a simple main method demonstrating the usage of your circular queue with some enqueue and dequeue operations.