Lila25mila
15 березня 2019 р. 14:22

Черга

Черга – це корисна структура даних у програмуванні. Уявіть чергу квитків поза кінозалом, де перша людина, що входить у чергу, є першою людиною, яка отримує квиток.


Черга слідує правилу «першим прийшов – першим обслужений» (First In First Out – FIFO) – елемент, який йде першим, – це елемент, який виходить першим.

Розглянемо рисунок. Оскільки 1 поміщена в чергу до 2, вона так само піде першою із черги. Це слідує правилу FIFO.

З погляду програмування, розміщення елемента у чергу (empty queue - порожня черга) називається "enqueue" (постановка у чергу), а видалення елемента з черги - "dequeue" (зняття черги).

Ми можемо реалізувати чергу будь-якою мовою програмування, такою як C, C++, Java, Python або C#, майже з однаковою специфікацією.

Технічні характеристики черги

Черга - це об'єкт або, конкретніше, абстрактна структура даних (ADT), яка дозволяє виконувати наступні операції:

  • Enqueue: додати елемент до кінця черги;
  • Dequeue: видалити елемент із початку черги;
  • IsEmpty: перевірити, чи порожня черга;
  • IsFull: перевірте, чи заповнена черга;
  • Peek: отримати значення початку черги, не видаляючи його.
Як працює черга

Операції з чергами працюють таким чином:

  1. Два вказівники, звані FRONT та REAR, використовуються для відстеження першого та останнього елементів у черзі.
  2. При ініціалізації черги ми встановлюємо значення FRONT та REAR рівним -1.
  3. При додаванні елемента ми збільшуємо значення індексу REAR і поміщаємо новий елемент у положення, яке вказує REAR.
  4. При видаленні елемента з черги ми повертаємо значення, яке вказує FRONT, і збільшуємо індекс FRONT.
  5. Перед постановкою на чергу ми перевіряємо, чи заповнена черга.
  6. Перед зняттям черги ми перевіряємо, чи порожня черга.
  7. При ініціалізації першого елемента ми встановлюємо значення FRONT 0.
  8. При видаленні останнього елемента ми скидаємо значення FRONT і REAR -1.

Реалізація черги мовою програмування

Найбільш поширена реалізація черги використовує масиви, але також черга може бути з використанням списків.

Реалізація з використанням C-програмування
  1. #include<stdio.h>
  2. #define SIZE 5
  3.  
  4. void enQueue(int);
  5. void deQueue();
  6. void display();
  7.  
  8. int items[SIZE], front = -1, rear = -1;
  9.  
  10. int main()
  11. {
  12. //deQueue невозможно в пустой очереди
  13. deQueue();
  14.  
  15. //enQueue 5 elements
  16. enQueue(1);
  17. enQueue(2);
  18. enQueue(3);
  19. enQueue(4);
  20. enQueue(5);
  21.  
  22. //6-й элемент не может быть добавлен в очередь, потому что очередь заполнена
  23. enQueue(6);
  24.  
  25. display();
  26.  
  27. //deQueue удаляет элемент, введенный первым, т.е. 1
  28. deQueue();
  29.  
  30. //Теперь у нас всего 4 элемента
  31. display();
  32.  
  33. return 0;
  34.  
  35. }
  36.  
  37. void enQueue(int value){
  38. if(rear == SIZE-1)
  39. printf("\nQueue is Full!!");
  40. else {
  41. if(front == -1)
  42. front = 0;
  43. rear++;
  44. items[rear] = value;
  45. printf("\nInserted -> %d", value);
  46. }
  47. }
  48.  
  49. void deQueue(){
  50. if(front == -1)
  51. printf("\nQueue is Empty!!");
  52. else{
  53. printf("\nDeleted : %d", items[front]);
  54. front++;
  55. if(front > rear)
  56. front = rear = -1;
  57. }
  58. }
  59.  
  60. void display(){
  61. if(rear == -1)
  62. printf("\nQueue is Empty!!!");
  63. else{
  64. int i;
  65. printf("\nQueue elements are:\n");
  66. for(i=front; i<=rear; i++)
  67. printf("%d\t",items[i]);
  68. }
  69. }

Коли ви запускаєте цю програму, ви отримуєте таке:

  1. Queue is Empty!!
  2. Inserted -> 1
  3. Inserted -> 2
  4. Inserted -> 3
  5. Inserted -> 4
  6. Inserted -> 5
  7. Queue is Full!!
  8. Queue elements are:
  9. 1 2 3 4 5
  10. Deleted : 1
  11. Queue elements are:
  12. 2 3 4 5
Реалізація з використанням програмування на C++
  1. #include <iostream>
  2. #define SIZE 5
  3.  
  4. using namespace std;
  5.  
  6. class Queue {
  7. private:
  8. int items[SIZE], front, rear;
  9.  
  10. public:
  11. Queue(){
  12. front = -1;
  13. rear = -1;
  14. }
  15.  
  16. bool isFull(){
  17. if(front == 0 && rear == SIZE - 1){
  18. return true;
  19. }
  20. return false;
  21. }
  22.  
  23. bool isEmpty(){
  24. if(front == -1) return true;
  25. else return false;
  26. }
  27.  
  28. void enQueue(int element){
  29. if(isFull()){
  30. cout << "Queue is full";
  31. } else {
  32. if(front == -1) front = 0;
  33. rear++;
  34. items[rear] = element;
  35. cout << endl << "Inserted " << element << endl;
  36. }
  37. }
  38.  
  39. int deQueue(){
  40. int element;
  41. if(isEmpty()){
  42. cout << "Queue is empty" << endl;
  43. return(-1);
  44. } else {
  45. element = items[front];
  46. if(front >= rear){
  47. front = -1;
  48. rear = -1;
  49. } /* В Q есть только один элемент, поэтому мы удаляем очередь после удаления. */
  50. else {
  51. front++;
  52. }
  53. cout << endl << "Deleted -> " << element << endl;
  54. return(element);
  55. }
  56. }
  57.  
  58. void display()
  59. {
  60. /* Функция для отображения элементов очереди */
  61. int i;
  62. if(isEmpty()) {
  63. cout << endl << "Empty Queue" << endl;
  64. }
  65. else
  66. {
  67. cout << endl << "Front -> " << front;
  68. cout << endl << "Items -> ";
  69. for(i=front; i<=rear; i++)
  70. cout << items[i] << ""\t";
  71. cout << endl << "Rear -> " << rear << endl;
  72. }
  73. }
  74.  
  75. };
  76.  
  77.  
  78. int main()
  79. {
  80. Queue q;
  81.  
  82. //deQueue невозможно в пустой очереди
  83. q.deQueue();
  84.  
  85. //enQueue 5 элементов
  86. q.enQueue(1);
  87. q.enQueue(2);
  88. q.enQueue(3);
  89. q.enQueue(4);
  90. q.enQueue(5);
  91.  
  92. //6-й элемент не может быть добавлен в очередь, потому что очередь заполнена
  93. q.enQueue(6);
  94.  
  95. q.display();
  96.  
  97. //deQueue удаляет элемент, введенный первым, т.е. 1
  98. q.deQueue();
  99.  
  100. //Теперь у нас всего 4 элемента
  101. q.display();
  102.  
  103. return 0;
  104. }

Після запуску ми отримаємо:

  1. Queue is empty
  2.  
  3. Inserted 1
  4.  
  5. Inserted 2
  6.  
  7. Inserted 3
  8.  
  9. Inserted 4
  10.  
  11. Inserted 5
  12. Queue is full
  13. Front -> 0
  14. Items -> 1 2 3 4 5
  15. Rear -> 4
  16.  
  17. Deleted -> 1
  18.  
  19. Front -> 1
  20. Items -> 2 3 4 5
  21. Rear -> 4
Обмеження цієї реалізації

Як ви можете бачити на зображенні нижче, через деякий час після додавання в чергу та видалення з черги розмір черги був зменшений.

Індекси 0 та 1 можуть використовуватися тільки після скидання черги, коли всі елементи видалені.

Змінюючи код для черги, ми можемо використовувати простір шляхом реалізації модифікованої черги, яка називається циклічною чергою.

По статті запитували0питання

2

Вам це подобається? Поділіться в соціальних мережах!

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
  • Останні коментарі
  • Evgenii Legotckoi
    16 квітня 2025 р. 17:08
    Благодарю за отзыв. И вам желаю всяческих успехов!
  • IscanderChe
    12 квітня 2025 р. 17:12
    Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
  • AK
    01 квітня 2025 р. 11:41
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    09 березня 2025 р. 21:02
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    09 березня 2025 р. 16:14
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…