#include <iostream>
// Define the maximum capacity for the queue.
#define MAX_SIZE 5
/**
* @class LinearQueue
* @brief Implements a basic Queue data structure using a fixed-size array.
* * Follows the First-In, First-Out (FIFO) principle.
* * This implementation is simpler but suffers from space inefficiency
* as the 'front' index keeps moving forward.
*/
class LinearQueue {
private:
// Array to store queue elements
int arr[MAX_SIZE];
// Index of the front element (where dequeue happens)
int front;
// Index of the rear element (where enqueue happens)
int rear;
public:
/**
* @brief Constructor for the LinearQueue.
*/
LinearQueue() {
// Initialize front and rear to -1 to signify an empty queue.
front = -1;
rear = -1;
}
/**
* @brief Checks if the queue is empty.
* @return true if the queue is empty, false otherwise.
*/
bool isEmpty() const {
// The queue is empty when both front and rear are -1
return front == -1;
}
/**
* @brief Checks if the queue is completely full.
* @return true if the queue is full, false otherwise.
*/
bool isFull() const {
// The queue is full when the rear pointer reaches the last index (MAX_SIZE - 1)
return rear == MAX_SIZE - 1;
}
/**
* @brief Adds an element to the rear of the queue (Enqueue).
* @param data The integer value to be inserted.
*/
void enqueue(int data) {
if (isFull()) {
std::cout << "ERROR: Queue Overflow! Cannot enqueue element " << data << ". Queue is full.\n";
return;
}
if (isEmpty()) {
// If the queue was empty, set front to 0
front = 0;
}
// Always increment rear and insert the new element
rear++;
arr[rear] = data;
std::cout << "Enqueued: " << data << " to the queue.\n";
}
/**
* @brief Removes and returns the element from the front of the queue (Dequeue).
* @return The integer value removed from the queue.
*/
int dequeue() {
if (isEmpty()) {
std::cout << "ERROR: Queue Underflow! Cannot dequeue element. Queue is empty.\n";
return -1; // Indicate error
}
int dequeuedValue = arr[front];
std::cout << "Dequeued: " << dequeuedValue << " from the queue.\n";
if (front == rear) {
// If the last element is removed, reset the queue to empty state
front = -1;
rear = -1;
} else {
// Move front forward (this is where space is 'wasted' in linear queue)
front++;
}
return dequeuedValue;
}
/**
* @brief Utility function to display the current elements in the queue.
*/
void display() const {
if (isEmpty()) {
std::cout << "Queue is currently empty.\n";
return;
}
std::cout << "Current Queue (Front -> Rear): ";
for (int i = front; i <= rear; i++) {
std::cout << arr[i] << (i == rear ? "" : " -> ");
}
std::cout << "\n";
}
};
/**
* @brief Main function to demonstrate the LinearQueue class functionality.
*/
int main() {
LinearQueue q;
std::cout << "--- Initial State ---\n";
std::cout << "Is Empty: " << (q.isEmpty() ? "True" : "False") << "\n";
// 1. Enqueue Operations
std::cout << "\n--- Enqueuing elements ---\n";
q.enqueue(100); // front=0, rear=0
q.enqueue(200); // front=0, rear=1
q.enqueue(300); // front=0, rear=2
q.display();
// 2. Dequeue Operations
std::cout << "\n--- Dequeuing elements (FIFO) ---\n";
q.dequeue(); // 100 is removed, front=1, rear=2
q.dequeue(); // 200 is removed, front=2, rear=2
q.display();
// 3. Overflow and Inefficiency Demonstration (MAX_SIZE is 5)
std::cout << "\n--- Demonstrating Fullness and Inefficiency ---\n";
q.enqueue(400); // front=2, rear=3
q.enqueue(500); // front=2, rear=4 (Queue is now full)
q.display();
std::cout << "Is Full: " << (q.isFull() ? "True" : "False") << "\n";
// 4. Overflow Test
q.enqueue(600); // Should fail due to overflow
// Note: The first two array slots (index 0 and 1) are empty
// but cannot be reused because 'rear' cannot decrement. This is the
// fundamental inefficiency of the simple linear array queue.
// 5. Empty the queue
std::cout << "\n--- Emptying the queue ---\n";
q.dequeue();
q.dequeue();
q.dequeue(); // 500 is removed. front=-1, rear=-1
// 6. Underflow Test
q.dequeue(); // Should fail due to underflow
std::cout << "Is Empty: " << (q.isEmpty() ? "True" : "False") << "\n";
return 0;
}