Lila25mila
20 марта 2019 г. 16:25

Круговая Очередь

Циклическая очередь позволяет избежать потери места в обычной реализации очереди с использованием массивов.


DeQueue - удаление элемента из очереди;
FRONT и REAR - два указателя, используемые для отслеживания первого и последнего элементов в очереди.

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

Индексы 0 и 1 могут использоваться только после сброса очереди, когда все элементы сняты.

Как работает круговая очередь

Циклическая очередь работает по процессу циклического приращения, то есть когда мы пытаемся увеличить любую переменную и достигаем конца очереди, мы начинаем с начала очереди по модулю деления с размером очереди.

То есть:

  1. if REAR + 1 == 5 (overflow!), REAR = (REAR + 1)%5 = 0 (start of queue)

Операции с очередями работают следующим образом:

  • Два указателя, называемые FRONT и REAR, используются для отслеживания первого и последнего элементов в очереди.
  • При инициализации очереди мы устанавливаем значение FRONT и REAR равным -1.
  • При добавления элемента мы постепенно увеличиваем значение индекса REAR и помещаем новый элемент в положение, на которое указывает REAR.
  • При снятии очереди с элемента мы возвращаем значение, на которое указывает FRONT, и постепенно увеличиваем индекс FRONT.
  • Перед постановкой в очередь мы проверяем, заполнена ли очередь.
  • Перед снятием очереди мы проверяем, пуста ли очередь.
  • При инициализации первого элемента мы устанавливаем значение FRONT в 0.
  • При удалении последнего элемента мы сбрасываем значения FRONT и REAR в -1.

Однако проверка на полную очередь имеет новый дополнительный пункт:

  • Случай 1: FRONT = 0 && REAR == РАЗМЕР - 1
  • Случай 2: ПЕРЕДНЯЯ = ЗАДНЯЯ + 1

Второй случай происходит, когда REAR начинается с 0 из-за кругового приращения, и когда его значение всего на 1 меньше значения FRONT, очередь заполнена.

Реализация циклической очереди на языке программирования

Наиболее распространенная реализация очереди использует массивы, но также может возможна реализация с использованием списков.

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

Когда вы запустите эту программу, получите следующее:

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

Когда вы запустите эту программу, получите следующее:

  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.  
  13. Queue is full
  14. Front -> 0
  15. Items -> 12345
  16. Rear -> 4
  17. Deleted Element is 1
  18. Front -> 1
  19. Items -> 2345
  20. Rear -> 4
  21. Inserted 7
  22.  
  23. Front -> 1
  24. Items -> 23457
  25. Rear -> 0
  26. Queue is full

По статье задано0вопрос(ов)

2

Вам это нравится? Поделитесь в социальных сетях!

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь