Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Отчёт_Списки.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
262.9 Кб
Скачать

Очередь

Очередь (queue) — это структура данных, которая сохраняет элементы в списке и обеспечивает доступ к данным только в двух концах списка (рис. 5.4). Элемент вставляется в конец списка и удаляется из начала списка. Приложения используют очередь для хранения элементов в порядке их поступления.

Э лементы удаляются из очереди в том же порядке, в котором они сохраняются и, следовательно, очередь обеспечивает FIFO (first-in/first-out) или FCFS- упорядочение (first-come/first-served). Обслуживание клиентов в очереди и буферизация задач принтера в системе входных и выходных потоков принтера — это классические примеры очередей.

Очередь включает список и определенные ссылки на начальную и конечную позиции. Эти позиции используются для вставки и удаления элементов очереди. Подобно стеку, очередь сохраняет элементы параметризованного типа DataType. Подобно стеку, абстрактная очередь не ограничивает количество элементов ввода. Однако, если для реализации списка используется массив, может возникнуть условие полной очереди.

ADT формат

ADT Queue

Данные

Список элементов

front: позиция первого элемента в очереди

rear: позиция последнего элемента в очереди

count: число элементов в очереди в любое данное время

Операции

Конструктор

Начальные значения: Нет

Процесс: Инициализация начала и конца очереди.

QLength

Вход: Нет

Предусловия: Нет

Процесс: Определение количества элементов в очереди

Выход: Возвращать количество элементов в очереди.

Постусловия: Нет

QEmpty

Вход: Нет

Предусловия: Нет

Процесс: Проверка: пуста ли очередь.

Выход: Возвращать 1 (True), если очередь пуста и 0 (False)

иначе. Заметьте, что это условие эквивалентно

проверке, равна ли QLength 0.

Постусловия: Нет

QDelete

Вход: Нет

Предусловия: Очередь не пуста.

Процесс: Удаление элемента из начала очереди.

Выход: Взвращать элемент, удаляемый из очереди.

Постусловия: Элемент удаляется из очереди.

Qlnsert

Вход: Элемент для сохранения в очереди.

Предусловия: Нет

Процесс: Запись элемента в конец очереди.

Выход: Нет

Постусловия: Новый элемент добавляется в очередь

QFront

Вход: Нет

Предусловия: Очередь не пуста.

Процесс: Выборка значения элемента в начале очереди.

Выход: Возвращать значение элемента в начале очереди.

Постусловия: Нет

ClearQueue

Вход: Нет

Предусловия: Нет

Процесс: Удаление всех элементов из очереди и восстановление

начальных условий.

Выход: Нет

Постусловия: Очередь пуста.

Конец ADT Queue

Класс Queue

Класс Queue реализует ADT, используя массив для сохранения списка элементов и определяя переменные, которые поддерживают позиции front и rear. Так как для реализации списка используется массив, класс содержит метод Qfull для проверки, заполнен ли массив.

Реализация: круговая модель.

Наша реализация очереди вводит круговую модель. Вместо сдвига элементов влево, когда один элемент удаляется, элементы очереди организованы логически в окружность. Переменная front всегда является местоположением первого элемента очереди, и она продвигается вправо по кругу по мере выполнения удалений. Переменная rear является местоположением, где происходит следующая вставка. После вставки rear перемещается по кругу вправо. Переменная count поддерживает запись количества элементов в очереди, и, если счетчик count равен значению size очередь заполнена.

Реализуем круговое движение, используя операцию остатка от деления:

  • Перемещение конца очереди вперед: rear = (rear+1)%MaxQSize;

  • Перемещение начала вперед: front = (front+1)%MaxQSize;

Листинг 13. Очередь

Очередь

#pragma once

#include <iostream>

#include <cstdlib>

// максимальный размер списка очереди

template<class DType>

class Queue

{

private:

// Массив и параметры очереди

int front, rear, count;

DType *qlist;

//Размер массива

int size;

public:

// конструктор

Queue(int size);

~Queue();

// операции модификации очереди

void qInsert(const DType &item);

DType qDelete(void);

void qClear(void);

// операции доступа

DType qFront(void) const;

// методы тестирования очереди

int qLength(void) const { return count; }

int isEmpty(void) const {return !count; }

int isFull(void) const {return count==size;}

};

// инициализация данных-членов: front, rear, count, size

template<class DType>

Queue<DType>::Queue (int s) : front(0), rear(0), count(0), size(s)

{

qlist = new DType[s];

}

template<class DType>

Queue<DType>::~Queue()

{

delete [] qlist;

}

// вставить item в очередь

template<class DType>

void Queue<DType>::qInsert (const DType &item)

{

// закончить программу, если очередь заполнена

if (isFull())

{

std::cerr << "Переполнение очереди!" << std::endl;

exit(1);

}

// увеличить count, присвоить значение item элементу массива

// изменить значение rear

count++;

qlist[rear] = item;

rear = (rear+1) % size;

}

// удалить элемент из начала очереди

// и возвратить его значение

template<class DType>

DType Queue<DType>::qDelete()

{

DType temp;

// если очередь пуста, закончить программу)

if(isEmpty())

{

std::cerr << "Удаление из пустой очереди!" << std::endl;

exit(1);

}

// записать значение в начало очереди

temp = qlist[front];

// уменьшить count на единицу

// продвинуть начало очередии возвратить прежнее значение

//из начала

count--;

front = (front+1) % size;

return temp;

}

template<class DType>

DType Queue<DType>::qFront() const

{

if(isEmpty())

{

std::cerr << "Удаление из пустой очереди!" << std::endl;

exit(1);

}

return qlist[front];

}

template<class DType>

void Queue<DType>::qClear()

{

front = 0;

rear = 0;

count = 0;

}

Main:

#include <iostream>

#include "queue.h"

using namespace std;

int main(int argc, char *argv[])

{

system("chcp 65001");

const int amount = 10;

Queue<int> test(amount);

cout << " Пуст? " << boolalpha << (bool) test.isEmpty() << endl;

cout << " Кол-во: " << test.qLength() << endl;

for (int i=0; i<amount; i++)

test.qInsert(i+1);

cout << " Полон? " << boolalpha << (bool) test.isFull() << endl;

cout << " Кол-во: " << test.qLength() << endl;

cout << " 1-ый эл-нт: " << test.qFront() << endl;

cout << " Проверка очереди:\n";

for (int i=0; i<amount; i++)

cout << test.qDelete() << endl;

return 0;

}

Результат:

Пуст? true

Кол-во: 0

Полон? true

Кол-во: 10

1-ый эл-нт: 1

Проверка очереди:

1

2

3

4

5

6

7

8

9

10