
- •Адресные типы
- •Использование динамической памяти
- •Линейные списки
- •Формы представления линейных списков в оперативной памяти
- •Стеки, очереди, деки
- •Представление стека в непрерывной памяти (в виде массива)
- •Представление стека в связанной памяти (в виде односвязного списка)
- •Очереди
- •Представление очереди в непрерывной памяти (в виде массива)
- •Представление очереди в связанной памяти (в виде односвязного списка)
- •Односвязный список
- •Двусвязный список
- •Кольцевые списки
- •Сортировка с помощью прямого выбора
- •Сортировка с помощью прямого обмена (пузырьковая)
- •Оценка затрат на поиск элемента
Очереди
ОЧЕРЕДЬ (Queue, дисциплина обслуживания FIFO, First-In-First-Out-"первым пришел-первым ушел")
Линейный список, в котором операция исключения (и обычно всякий доступ) разрешена на одном его конце (в начале), а включения - на другом (в конце).
БАЗОВЫЕ ОПЕРАЦИИ:
Добавить новый элемент в конец очереди
Удалить из очереди первый элемент
Получить доступ к крайним элементам.
ЕСЛИ Памяти нет ТО Переполнение ИНАЧЕ Добавить узел в конец очереди Записать Х в последний узел ВСЕ-ЕСЛИ |
ЕСЛИ Очередь пуста ТО Нехватка ИНАЧЕ Переписать содержимое из узла - начала очереди в X Удалить узел из начала очереди ВСЕ-ЕСЛИ |
Представление очереди в непрерывной памяти (в виде массива)
[Д. Прайс, стр. 181-183]
рис.5. Очередь в непрерывной памяти
рис.6. Очередь в виде «кольцевого» массива |
Const QUEUESIZE =… Tyре Queue=record OBJ:array[0..QUEUESIZE] of real; {указатели на первый и последний элементы} FRONT, REAR: 0..QUEUESIZE; End; Var Q:QUEUE;
Очередь, представленную на рис. 5, можно рассматиривать в виде «кольцевого» массива (рис.6), в котором не используется один из элементов (заштрихованный узел). |
В описании типа Queue массив OBJ начинается с 0, т.е. массив значений содержит QUEUESIZE+1 компонент.
Так как начало и конец очереди непрерывно перемещаются в пределах массива, удобно представить массив в виде кольца. Для обхода «по кольцу» используется операция mod. Если REAR<QUEUESIZE-1, то он увеличивается обычным способом. Если REAR равен QUEUESIZE-1, то он сбрасывается в 0:
REAR+1=(QUEUESIZE-1)+1=QUEUESIZE
QUEUESIZE mod QUEUESIZE=0
Элемент QUEUESIZE не используется для хранения значений.
При добавлении узла проверяется, что существует более 1 свободной позиции между FRONT и REAR (условие REAR=FRONT, перед проверкой REAR увеличивается на 1). Если существует только одна свободная позиция, очередь заполнена.
Procedure ADDQ (var Q:QUEUE; NEWOBJ:REAL); Begin With Q do Begin REAR:=(REAR+1) mod QUEUESIZE; IF REAR=FRONT THEN WRITELN('Очередь полна') ELSE OBJ[REAR]:=NEWOBJ END END; (* процедуры ADDQ *) |
procedure DELETEQ (var Q:QUEUE; var OLDOBJ:REAL); Begin with Q do IF REAR=FRONT THEN WRITELN('Очередь пуста') ELSE Begin FRONT:=(FRONT+1) mod QUEUESIZE; //сравните с псевдокодом OLDOBJ:=OBJ[FRONT] END END; (* процедуры DELETEQ *) |