|
1 | 1 | #include <iostream>
|
2 |
| -using namespace std; |
| 2 | +#include <cassert> // For test case assertions |
| 3 | +#include <stdexcept> // For runtime error handling |
3 | 4 |
|
4 |
| -// Define the maximum size of the queue. |
5 |
| -const int MAX_SIZE = 10; |
| 5 | +/** |
| 6 | + * @brief A class to represent a circular queue. |
| 7 | + * |
| 8 | + * This Queue class uses a fixed-size array to implement a circular queue. |
| 9 | + * It supports basic operations like enqueue, dequeue, and display. |
| 10 | + */ |
| 11 | +class Queue { |
| 12 | +private: |
| 13 | + static const int MAX_SIZE = 10; ///< The maximum number of elements the queue can hold |
| 14 | + int queue[MAX_SIZE]; ///< Array to store the queue elements |
| 15 | + int front; ///< Index pointing to the front of the queue |
| 16 | + int rear; ///< Index pointing to the next available position for inserting elements |
| 17 | + int count; ///< The number of elements currently in the queue |
6 | 18 |
|
7 |
| -int queue[MAX_SIZE]; // Queue array |
8 |
| -int front = 0; // Points to the front of the queue |
9 |
| -int rear = 0; // Points to the next available position for inserting elements |
10 |
| -int count = 0; // Keeps track of the number of elements in the queue |
| 19 | +public: |
| 20 | + /** |
| 21 | + * @brief Constructs a new Queue object. |
| 22 | + * |
| 23 | + * Initializes front, rear, and count to 0. |
| 24 | + */ |
| 25 | + Queue(); |
11 | 26 |
|
12 |
| -// Function to enqueue an element into the queue |
13 |
| -void Enqueue(int x) { |
14 |
| - // Check if the queue is full |
| 27 | + /** |
| 28 | + * @brief Enqueues an element into the queue. |
| 29 | + * |
| 30 | + * Adds an element to the rear of the queue. If the queue is full, it prints an overflow message. |
| 31 | + * |
| 32 | + * @param x The element to enqueue |
| 33 | + */ |
| 34 | + void Enqueue(int x); |
| 35 | + |
| 36 | + /** |
| 37 | + * @brief Dequeues an element from the queue. |
| 38 | + * |
| 39 | + * Removes the element from the front of the queue. If the queue is empty, it prints an underflow message. |
| 40 | + */ |
| 41 | + void Dequeue(); |
| 42 | + |
| 43 | + /** |
| 44 | + * @brief Displays the elements of the queue. |
| 45 | + * |
| 46 | + * Prints the elements of the queue from front to rear. If the queue is empty, it prints an appropriate message. |
| 47 | + */ |
| 48 | + void Show() const; |
| 49 | + |
| 50 | + /** |
| 51 | + * @brief Gets the current number of elements in the queue. |
| 52 | + * |
| 53 | + * @return The number of elements in the queue |
| 54 | + */ |
| 55 | + int getCount() const; |
| 56 | + |
| 57 | + /** |
| 58 | + * @brief Gets the front element of the queue. |
| 59 | + * |
| 60 | + * Returns the front element of the queue. Throws a runtime error if the queue is empty. |
| 61 | + * |
| 62 | + * @return The front element of the queue |
| 63 | + * @throws std::runtime_error if the queue is empty |
| 64 | + */ |
| 65 | + int getFrontElement() const; |
| 66 | + |
| 67 | + /** |
| 68 | + * @brief Gets the rear element of the queue. |
| 69 | + * |
| 70 | + * Returns the rear element of the queue. Throws a runtime error if the queue is empty. |
| 71 | + * |
| 72 | + * @return The rear element of the queue |
| 73 | + * @throws std::runtime_error if the queue is empty |
| 74 | + */ |
| 75 | + int getRearElement() const; |
| 76 | +}; |
| 77 | + |
| 78 | +// Constructor definition |
| 79 | +Queue::Queue() { |
| 80 | + front = 0; |
| 81 | + rear = 0; |
| 82 | + count = 0; |
| 83 | +} |
| 84 | + |
| 85 | +void Queue::Enqueue(int x) { |
15 | 86 | if (count == MAX_SIZE) {
|
16 |
| - cout << "\nOverflow: Queue is full, cannot enqueue " << x; |
| 87 | + std::cout << "\nOverflow: Queue is full, cannot enqueue " << x; |
17 | 88 | } else {
|
18 |
| - // Insert the element at the rear and move the rear pointer circularly |
19 | 89 | queue[rear] = x;
|
20 | 90 | rear = (rear + 1) % MAX_SIZE;
|
21 |
| - count++; // Increase the element count |
| 91 | + count++; |
22 | 92 | }
|
23 | 93 | }
|
24 | 94 |
|
25 |
| -// Function to dequeue an element from the queue |
26 |
| -void Dequeue() { |
27 |
| - // Check if the queue is empty |
| 95 | +void Queue::Dequeue() { |
28 | 96 | if (count == 0) {
|
29 |
| - cout << "\nUnderflow: Queue is empty, cannot dequeue"; |
| 97 | + std::cout << "\nUnderflow: Queue is empty, cannot dequeue"; |
30 | 98 | } else {
|
31 |
| - // Display the dequeued element and move the front pointer circularly |
32 |
| - cout << "\n" << queue[front] << " deleted"; |
| 99 | + std::cout << "\n" << queue[front] << " deleted"; |
33 | 100 | front = (front + 1) % MAX_SIZE;
|
34 |
| - count--; // Decrease the element count |
| 101 | + count--; |
35 | 102 | }
|
36 | 103 | }
|
37 | 104 |
|
38 |
| -// Function to display the elements of the queue |
39 |
| -void show() { |
| 105 | +void Queue::Show() const { |
40 | 106 | if (count == 0) {
|
41 |
| - cout << "\nQueue is empty"; |
| 107 | + std::cout << "\nQueue is empty"; |
42 | 108 | return;
|
43 | 109 | }
|
44 | 110 |
|
45 |
| - cout << "\nQueue elements: "; |
46 |
| - // Loop through the valid elements using modular arithmetic |
| 111 | + std::cout << "\nQueue elements: "; |
47 | 112 | for (int i = 0; i < count; i++) {
|
48 |
| - cout << queue[(front + i) % MAX_SIZE] << "\t"; |
| 113 | + std::cout << queue[(front + i) % MAX_SIZE] << "\t"; |
49 | 114 | }
|
50 | 115 | }
|
51 | 116 |
|
52 |
| -// Main function with a menu-driven approach for queue operations |
53 |
| -int main() { |
54 |
| - int choice, x; |
55 |
| - |
56 |
| - do { |
57 |
| - // Display menu |
58 |
| - cout << "\n\nMenu:"; |
59 |
| - cout << "\n1. Enqueue"; |
60 |
| - cout << "\n2. Dequeue"; |
61 |
| - cout << "\n3. Show"; |
62 |
| - cout << "\n0. Exit"; |
63 |
| - cout << "\nEnter your choice: "; |
64 |
| - cin >> choice; |
65 |
| - |
66 |
| - switch (choice) { |
67 |
| - case 1: |
68 |
| - // Enqueue an element |
69 |
| - cout << "\nInsert: "; |
70 |
| - cin >> x; |
71 |
| - Enqueue(x); |
72 |
| - break; |
73 |
| - |
74 |
| - case 2: |
75 |
| - // Dequeue an element |
76 |
| - Dequeue(); |
77 |
| - break; |
78 |
| - |
79 |
| - case 3: |
80 |
| - // Show the current queue elements |
81 |
| - show(); |
82 |
| - break; |
83 |
| - |
84 |
| - case 0: |
85 |
| - // Exit the loop |
86 |
| - cout << "\nExiting..."; |
87 |
| - break; |
88 |
| - |
89 |
| - default: |
90 |
| - // Handle invalid input |
91 |
| - cout << "\nInvalid choice, please try again."; |
92 |
| - } |
93 |
| - |
94 |
| - } while (choice != 0); // Continue until the user chooses to exit |
| 117 | +int Queue::getCount() const { |
| 118 | + return count; |
| 119 | +} |
| 120 | + |
| 121 | +int Queue::getFrontElement() const { |
| 122 | + if (count == 0) { |
| 123 | + throw std::runtime_error("Queue is empty"); |
| 124 | + } |
| 125 | + return queue[front]; |
| 126 | +} |
| 127 | + |
| 128 | +int Queue::getRearElement() const { |
| 129 | + if (count == 0) { |
| 130 | + throw std::runtime_error("Queue is empty"); |
| 131 | + } |
| 132 | + return queue[(rear - 1 + MAX_SIZE) % MAX_SIZE]; |
| 133 | +} |
| 134 | + |
| 135 | +/** |
| 136 | + * @brief Runs automated test cases for the Queue class. |
| 137 | + * |
| 138 | + * This function tests the queue functionality including enqueueing, dequeueing, overflow, and underflow scenarios. |
| 139 | + */ |
| 140 | +void runTestCases() { |
| 141 | + Queue q; |
95 | 142 |
|
| 143 | + // Test case 1: Enqueue elements |
| 144 | + q.Enqueue(10); |
| 145 | + q.Enqueue(20); |
| 146 | + q.Enqueue(30); |
| 147 | + assert(q.getFrontElement() == 10); |
| 148 | + assert(q.getRearElement() == 30); |
| 149 | + std::cout << "\nTest Case 1 passed: Enqueue elements"; |
| 150 | + |
| 151 | + // Test case 2: Dequeue an element |
| 152 | + q.Dequeue(); // Should dequeue 10 |
| 153 | + assert(q.getFrontElement() == 20); // Front should now be 20 |
| 154 | + assert(q.getCount() == 2); // Count should decrease to 2 |
| 155 | + std::cout << "\nTest Case 2 passed: Dequeue element"; |
| 156 | + |
| 157 | + // Test case 3: Enqueue and dequeue combination |
| 158 | + q.Enqueue(40); // Enqueue one more element |
| 159 | + q.Enqueue(50); |
| 160 | + assert(q.getRearElement() == 50); // The last enqueued element should be 50 |
| 161 | + q.Dequeue(); // Should dequeue 20 |
| 162 | + assert(q.getFrontElement() == 30); // Front element should now be 30 |
| 163 | + std::cout << "\nTest Case 3 passed: Enqueue and dequeue combination"; |
| 164 | + |
| 165 | + // Test case 4: Overflow |
| 166 | + for (int i = 0; i < 7; i++) { |
| 167 | + q.Enqueue(60 + i); // Keep adding until the queue is full |
| 168 | + } |
| 169 | + q.Enqueue(100); // This should trigger overflow |
| 170 | + assert(q.getCount() == 10); // Queue should be full |
| 171 | + std::cout << "\nTest Case 4 passed: Overflow check"; |
| 172 | + |
| 173 | + // Test case 5: Underflow |
| 174 | + for (int i = 0; i < 10; i++) { |
| 175 | + q.Dequeue(); // Dequeue all elements |
| 176 | + } |
| 177 | + q.Dequeue(); // This should trigger underflow |
| 178 | + assert(q.getCount() == 0); // Queue should be empty |
| 179 | + std::cout << "\nTest Case 5 passed: Underflow check"; |
| 180 | + |
| 181 | + std::cout << "\nAll test cases passed!\n"; |
| 182 | +} |
| 183 | + |
| 184 | +/** |
| 185 | + * @brief The main function to run the test cases. |
| 186 | + * |
| 187 | + * This function runs the automated test cases for the queue. |
| 188 | + * |
| 189 | + * @return int |
| 190 | + */ |
| 191 | +int main() { |
| 192 | + runTestCases(); // Run automated test cases |
96 | 193 | return 0;
|
97 | 194 | }
|
| 195 | + |
0 commit comments