fork download
  1. #include <iostream>
  2. #include <stdexcept>
  3. #include <cstddef>
  4.  
  5. template <typename T>
  6. class CircularQueue {
  7. private:
  8. T* data; // Массив для хранения элементов
  9. std::size_t capacity; // Максимальная вместимость
  10. std::size_t frontIndex; // Индекс первого элемента
  11. std::size_t rearIndex; // Индекс следующей свободной позиции
  12. std::size_t count; // Текущее количество элементов
  13.  
  14. public:
  15. // Конструктор
  16. explicit CircularQueue(std::size_t capacity)
  17. : data(nullptr),
  18. capacity(capacity),
  19. frontIndex(0),
  20. rearIndex(0),
  21. count(0) {
  22.  
  23. if (capacity == 0) {
  24. throw std::invalid_argument(
  25. "Размер очереди должен быть больше нуля"
  26. );
  27. }
  28.  
  29. data = new T[capacity];
  30. }
  31.  
  32. // Деструктор
  33. ~CircularQueue() {
  34. delete[] data;
  35. }
  36.  
  37. // Запрещаем копирование для безопасной работы с динамической памятью
  38. CircularQueue(const CircularQueue&) = delete;
  39. CircularQueue& operator=(const CircularQueue&) = delete;
  40.  
  41. // Проверка, пуста ли очередь
  42. bool isEmpty() const noexcept {
  43. return count == 0;
  44. }
  45.  
  46. // Проверка, заполнена ли очередь
  47. bool isFull() const noexcept {
  48. return count == capacity;
  49. }
  50.  
  51. // Получение текущего количества элементов
  52. std::size_t size() const noexcept {
  53. return count;
  54. }
  55.  
  56. // Получение максимального количества элементов
  57. std::size_t maxSize() const noexcept {
  58. return capacity;
  59. }
  60.  
  61. // Добавление элемента в конец очереди
  62. void enqueue(const T& value) {
  63. if (isFull()) {
  64. throw std::overflow_error("Очередь заполнена");
  65. }
  66.  
  67. data[rearIndex] = value;
  68.  
  69. // Циклический переход к следующей позиции массива
  70. rearIndex = (rearIndex + 1) % capacity;
  71.  
  72. ++count;
  73. }
  74.  
  75. // Удаление элемента из начала очереди
  76. void dequeue() {
  77. if (isEmpty()) {
  78. throw std::underflow_error("Очередь пуста");
  79. }
  80.  
  81. // Элементы не сдвигаются, изменяется только индекс начала
  82. frontIndex = (frontIndex + 1) % capacity;
  83.  
  84. --count;
  85. }
  86.  
  87. // Получение первого элемента очереди
  88. T& front() {
  89. if (isEmpty()) {
  90. throw std::underflow_error("Очередь пуста");
  91. }
  92.  
  93. return data[frontIndex];
  94. }
  95.  
  96. const T& front() const {
  97. if (isEmpty()) {
  98. throw std::underflow_error("Очередь пуста");
  99. }
  100.  
  101. return data[frontIndex];
  102. }
  103.  
  104. // Получение последнего элемента очереди
  105. T& back() {
  106. if (isEmpty()) {
  107. throw std::underflow_error("Очередь пуста");
  108. }
  109.  
  110. std::size_t index =
  111. (rearIndex + capacity - 1) % capacity;
  112.  
  113. return data[index];
  114. }
  115.  
  116. const T& back() const {
  117. if (isEmpty()) {
  118. throw std::underflow_error("Очередь пуста");
  119. }
  120.  
  121. std::size_t index =
  122. (rearIndex + capacity - 1) % capacity;
  123.  
  124. return data[index];
  125. }
  126.  
  127. // Полная очистка очереди
  128. void clear() noexcept {
  129. frontIndex = 0;
  130. rearIndex = 0;
  131. count = 0;
  132. }
  133.  
  134. // Вывод элементов очереди
  135. void print() const {
  136. if (isEmpty()) {
  137. std::cout << "Очередь: пуста\n";
  138. return;
  139. }
  140.  
  141. std::cout << "Очередь: ";
  142.  
  143. for (std::size_t i = 0; i < count; ++i) {
  144. std::size_t index =
  145. (frontIndex + i) % capacity;
  146.  
  147. std::cout << data[index];
  148.  
  149. if (i + 1 < count) {
  150. std::cout << " ";
  151. }
  152. }
  153.  
  154. std::cout << '\n';
  155. }
  156.  
  157. // Вывод внутреннего состояния циклического массива
  158. void printState() const {
  159. std::cout << "Индекс начала (front): " << frontIndex
  160. << ", индекс конца (rear): " << rearIndex
  161. << ", размер: " << count
  162. << ", вместимость: " << capacity
  163. << '\n';
  164. }
  165. };
  166.  
  167.  
  168. int main() {
  169. try {
  170. // Создание очереди вместимостью 5 элементов
  171. CircularQueue<int> queue(5);
  172.  
  173. // ---------------------------------------------------------
  174. // 1. Начальное состояние
  175. // ---------------------------------------------------------
  176. std::cout << "=== 1. Начальное состояние очереди ===\n";
  177.  
  178. queue.print();
  179. queue.printState();
  180.  
  181. // ---------------------------------------------------------
  182. // 2. Добавление элементов
  183. // ---------------------------------------------------------
  184. std::cout << "\n=== 2. Добавление элементов ===\n";
  185.  
  186. queue.enqueue(10);
  187. queue.enqueue(20);
  188. queue.enqueue(30);
  189.  
  190. queue.print();
  191. queue.printState();
  192.  
  193. // ---------------------------------------------------------
  194. // 3. Просмотр первого и последнего элемента
  195. // ---------------------------------------------------------
  196. std::cout
  197. << "\n=== 3. Просмотр первого и последнего элемента ===\n";
  198.  
  199. std::cout << "Первый элемент: "
  200. << queue.front() << '\n';
  201.  
  202. std::cout << "Последний элемент: "
  203. << queue.back() << '\n';
  204.  
  205. // ---------------------------------------------------------
  206. // 4. Удаление элемента
  207. // ---------------------------------------------------------
  208. std::cout << "\n=== 4. Удаление элемента ===\n";
  209.  
  210. queue.dequeue();
  211.  
  212. std::cout << "После удаления первого элемента:\n";
  213. queue.print();
  214. queue.printState();
  215.  
  216. // ---------------------------------------------------------
  217. // 5. Проверка циклического массива
  218. // ---------------------------------------------------------
  219. std::cout << "\n=== 5. Проверка циклического массива ===\n";
  220.  
  221. queue.enqueue(40);
  222. queue.enqueue(50);
  223. queue.enqueue(60);
  224.  
  225. queue.print();
  226. queue.printState();
  227.  
  228. std::cout
  229. << "Освободившаяся позиция массива была использована повторно.\n"
  230. << "Элементы очереди не сдвигаются.\n";
  231.  
  232. // ---------------------------------------------------------
  233. // 6. Проверка заполнения очереди
  234. // ---------------------------------------------------------
  235. std::cout << "\n=== 6. Проверка заполнения очереди ===\n";
  236.  
  237. queue.print();
  238.  
  239. std::cout << "Очередь заполнена: "
  240. << (queue.isFull() ? "да" : "нет")
  241. << '\n';
  242.  
  243. // ---------------------------------------------------------
  244. // 7. Проверка переполнения
  245. // ---------------------------------------------------------
  246. std::cout << "\n=== 7. Проверка переполнения ===\n";
  247.  
  248. try {
  249. queue.enqueue(70);
  250. }
  251. catch (const std::overflow_error& error) {
  252. std::cout
  253. << "Переполнение обработано корректно: "
  254. << error.what() << '\n';
  255. }
  256.  
  257. // ---------------------------------------------------------
  258. // 8. Повторное использование освободившихся ячеек
  259. // ---------------------------------------------------------
  260. std::cout
  261. << "\n=== 8. Повторное использование освободившихся ячеек ===\n";
  262.  
  263. queue.dequeue();
  264. queue.dequeue();
  265.  
  266. std::cout << "После удаления двух элементов:\n";
  267. queue.print();
  268. queue.printState();
  269.  
  270. queue.enqueue(70);
  271. queue.enqueue(80);
  272.  
  273. std::cout << "После добавления новых элементов:\n";
  274. queue.print();
  275. queue.printState();
  276.  
  277. // ---------------------------------------------------------
  278. // 9. Проверка размера очереди
  279. // ---------------------------------------------------------
  280. std::cout << "\n=== 9. Проверка размера очереди ===\n";
  281.  
  282. std::cout << "Текущий размер очереди: "
  283. << queue.size() << '\n';
  284.  
  285. std::cout << "Максимальный размер очереди: "
  286. << queue.maxSize() << '\n';
  287.  
  288. std::cout << "Очередь пуста: "
  289. << (queue.isEmpty() ? "да" : "нет")
  290. << '\n';
  291.  
  292. std::cout << "Очередь заполнена: "
  293. << (queue.isFull() ? "да" : "нет")
  294. << '\n';
  295.  
  296. // ---------------------------------------------------------
  297. // 10. Очистка очереди
  298. // ---------------------------------------------------------
  299. std::cout << "\n=== 10. Очистка очереди ===\n";
  300.  
  301. queue.clear();
  302.  
  303. queue.print();
  304. queue.printState();
  305.  
  306. std::cout << "Очередь пуста: "
  307. << (queue.isEmpty() ? "да" : "нет")
  308. << '\n';
  309.  
  310. // ---------------------------------------------------------
  311. // 11. Проверка удаления из пустой очереди
  312. // ---------------------------------------------------------
  313. std::cout
  314. << "\n=== 11. Проверка удаления из пустой очереди ===\n";
  315.  
  316. try {
  317. queue.dequeue();
  318. }
  319. catch (const std::underflow_error& error) {
  320. std::cout
  321. << "Удаление из пустой очереди обработано корректно: "
  322. << error.what() << '\n';
  323. }
  324.  
  325. // ---------------------------------------------------------
  326. // 12. Повторное использование после очистки
  327. // ---------------------------------------------------------
  328. std::cout
  329. << "\n=== 12. Повторное использование после очистки ===\n";
  330.  
  331. queue.enqueue(100);
  332. queue.enqueue(200);
  333.  
  334. queue.print();
  335. queue.printState();
  336.  
  337. std::cout << "Первый элемент: "
  338. << queue.front() << '\n';
  339.  
  340. std::cout << "Последний элемент: "
  341. << queue.back() << '\n';
  342.  
  343. std::cout
  344. << "\n=== Все проверки успешно завершены ===\n";
  345. }
  346. catch (const std::invalid_argument& error) {
  347. std::cerr
  348. << "Ошибка при создании очереди: "
  349. << error.what() << '\n';
  350.  
  351. return 1;
  352. }
  353. catch (const std::exception& error) {
  354. std::cerr
  355. << "Непредвиденная ошибка: "
  356. << error.what() << '\n';
  357.  
  358. return 1;
  359. }
  360.  
  361. return 0;
  362. }
Success #stdin #stdout 0.01s 5284KB
stdin
Standard input is empty
stdout
=== 1. Начальное состояние очереди ===
Очередь: пуста
Индекс начала (front): 0, индекс конца (rear): 0, размер: 0, вместимость: 5

=== 2. Добавление элементов ===
Очередь: 10 20 30
Индекс начала (front): 0, индекс конца (rear): 3, размер: 3, вместимость: 5

=== 3. Просмотр первого и последнего элемента ===
Первый элемент: 10
Последний элемент: 30

=== 4. Удаление элемента ===
После удаления первого элемента:
Очередь: 20 30
Индекс начала (front): 1, индекс конца (rear): 3, размер: 2, вместимость: 5

=== 5. Проверка циклического массива ===
Очередь: 20 30 40 50 60
Индекс начала (front): 1, индекс конца (rear): 1, размер: 5, вместимость: 5
Освободившаяся позиция массива была использована повторно.
Элементы очереди не сдвигаются.

=== 6. Проверка заполнения очереди ===
Очередь: 20 30 40 50 60
Очередь заполнена: да

=== 7. Проверка переполнения ===
Переполнение обработано корректно: Очередь заполнена

=== 8. Повторное использование освободившихся ячеек ===
После удаления двух элементов:
Очередь: 40 50 60
Индекс начала (front): 3, индекс конца (rear): 1, размер: 3, вместимость: 5
После добавления новых элементов:
Очередь: 40 50 60 70 80
Индекс начала (front): 3, индекс конца (rear): 3, размер: 5, вместимость: 5

=== 9. Проверка размера очереди ===
Текущий размер очереди: 5
Максимальный размер очереди: 5
Очередь пуста: нет
Очередь заполнена: да

=== 10. Очистка очереди ===
Очередь: пуста
Индекс начала (front): 0, индекс конца (rear): 0, размер: 0, вместимость: 5
Очередь пуста: да

=== 11. Проверка удаления из пустой очереди ===
Удаление из пустой очереди обработано корректно: Очередь пуста

=== 12. Повторное использование после очистки ===
Очередь: 100 200
Индекс начала (front): 0, индекс конца (rear): 2, размер: 2, вместимость: 5
Первый элемент: 100
Последний элемент: 200

=== Все проверки успешно завершены ===