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

9. Очередь. Основные операции для работы с очередью

Очередь - одномерная структура данных, для которой загрузка или извлечение элементов осуществляется с помощью указателей начала извлечения (head) и конца (tail) очереди в соответствии с правилом FIFO ("first-in, first-out" - "первым введен, первым выведен"), другими словами включение производится с одного, а исключение – с другого конца.

По мере постановки элементов в очередь ее конец будет продвигаться к концу массива, то же самое будет происходить с началом при их исключении. Выход из создавшегося положения - циклическая очередь, в ней мы считаем, что за последним элементом массива следует опять первый. Очевидно, что со временем указатель на конец при очередном включении элемента достигнет верхней границы той области памяти, которая выделена для очереди. Однако, если операции включения чередовались с операциями исключения элементов, то в начальной части отведенной под очередь памяти имеется свободное место. Для того, чтобы места, занимаемые исключенными элементами, могли быть повторно использованы, очередь замыкается в кольцо: указатели (на начало и на конец), достигнув конца выделенной области памяти, переключаются на ее начало. Такая организация очереди в памяти называется кольцевой очередью или циклическим буфером. Возможны, конечно, и другие варианты организации: например, всякий раз, когда указатель конца достигнет верхней границы памяти, сдвигать все непустые элементы очереди к началу области памяти, но как этот, так и другие варианты требуют перемещения в памяти элементов очереди и менее эффективны, чем кольцевая очередь.

В исходном состоянии указатели на начало и на конец указывают на начало области памяти. Равенство этих двух указателей (при любом их значении) является признаком пустой очереди. Если в процессе работы с кольцевой очередью число операций включения превышает число операций исключения, то может возникнуть ситуация, в которой указатель конца "догонит" указатель начала. Это ситуация заполненной очереди, но если в этой ситуации указатели сравняются, эта ситуация будет неотличима от ситуации пустой очереди. Для различения этих двух ситуаций к кольцевой очереди предъявляется требование, чтобы между указателем конца и указателем начала оставался "зазор" из свободных элементов. Когда этот "зазор" сокращается до одного элемента, очередь считается заполненной и дальнейшие попытки записи в нее блокируются.

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

Итак, основные операции над очередью - те же, что и над стеком - включение, исключение, определение размера, очистка, неразрушающее чтение.

10. Очередь с приоритетом. Основные операции для работы с очередью с приоритетом.

Очереди с приоритетами

В реальных задачах иногда возникает необходимость в формировании очередей, отличных от FIFO или LIFO. Порядок выборки элементов из таких очередей определяется приоритетами элементов. Приоритет в общем случае может быть представлен числовым значением, которое вычисляется либо на основании значений каких-либо полей элемента, либо на основании внешних факторов. Так, и FIFO, и LIFO-очереди могут трактоваться как приоритетные очереди, в которых приоритет элемента зависит от времени его включения в очередь. Приоритетная очередь — это абстрактный тип данных, предназначенный для представления взвешенных множеств. Множество называется взвешенным, если каждому его элементу однозначно соответствует число, называемое ключом или весом. При выборке элемента всякий раз выбирается элемент с наибольшим приоритетом, т.е. "первым включается - с высшим приоритетом исключается". Приоритетная очередь естественным образом используется в таких задачах, как сортировка элементов массива, поиск кратчайших путей от заданной вершины взвешенного графа до его остальных вершин, и во многих других.

Приоритетную очередь можно представить с помощью массива или списка элементов структурах - в смежном или связном представлении, но такие реализации неэффективны по времени выполнения основных операций. Так, например, поиск элемента с минимальным ключом в неупорядоченном массиве или списке требует последовательного просмотра всех его элементов. Если поддерживать упорядоченность массива или списка по ключу, то "неудобной" окажется операция вставки нового элемента.

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

Очередь с приоритетом — абстрактный тип данных в программировании поддерживающий три операции:

InsertWithPriority: добавить в очередь элемент с нaзначенным приоритетом

GetNext: извлечь из очереди и вернуть элемент с минимальным приоритетом

PeekAtNext (необязательная операция): просмотреть элемент с наивысшим приоритетом без извлечения

Говоря другим языком, очередь с приоритетом позволяет хранить пары (ключ, значение) и поддерживает операции добавления пары, поиска пары с минимальным ключом и извлечения пары с минимальным ключом:

INSERT(ключ, значение) — добавляет пару в хранилище;

MIN — возвращает пару с минимальным значением ключа;

EXTRACT_MIN — возвращает пару с минимальным значением ключа, удаляя её из хранилища;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]