Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.37 Mб
Скачать

5.2. Очереди 211

то, что членский фронт функции возвращает постоянную ссылку на вершину очереди.

Состояние ошибки происходит, звоня или фронта функций или dequeue на пустой очереди. Это сообщено, бросив исключение QueueEmpty, который определен в Кодовом Фрагменте 5.16.

класс QueueEmpty: общественный RuntimeException

общественность:

QueueEmpty (константа string& допускают ошибку): RuntimeException (допускают ошибку)

;

Кодовый Фрагмент 5.16: Исключение, брошенное фронтом функций или dequeue, когда обращено пустая очередь. Этот класс получен из RuntimeException от Раздела 2.4.

5.2.4 Простое основанное на множестве внедрение

Мы представляем простую реализацию очереди посредством множества, Q, со способностью

N, для хранения его элементов. Основной вопрос с этим внедрением решает, как отслеживать фронт и заднюю часть очереди.

Одна возможность состоит в том, чтобы приспособить подход, который мы использовали для внедрения стека. В частности позвольте Q [0] быть фронтом очереди и сделать, чтобы очередь выросла оттуда. Это не эффективное решение, однако, поскольку оно требует, чтобы мы двинулись, все элементы отправляют одной клетке множества каждый раз, когда мы выполняем dequeue операцию. Такое внедрение поэтому потребовало бы, чтобы Q (n) время выполнил функцию dequeue, где n - текущий ряд элементов в очереди. Если мы хотим достигнуть постоянного времени для каждой функции очереди, нам нужен другой подход.

Используя множество круглым способом

Чтобы избежать перемещать объекты, как только они размещены в Q, мы определяем три переменные, f, r,

n, у которых есть следующие значения:

f - индекс клетки Q хранение фронта очереди. Если очередь

непустой, это - индекс элемента, который будет удален dequeue.

r - индекс клетки Q после задней части очереди. Если очередь

не полный, это - индекс, где элемент вставлен, ставят в очередь.

n - текущий ряд элементов в очереди.

Первоначально, мы устанавливаем n = 0 и f = r = 0, указывая на пустую очередь. Когда мы

dequeue элемент с фронта очереди, мы декремент n и приращение f к следующей клетке в Q. Аналогично, когда мы ставим элемент в очередь, мы увеличиваем r и увеличиваем n. Это позволяет нам осуществлять ставить в очередь и функции dequeue в постоянное время

212

Глава 5. Стеки, очереди и Deques

Тем не менее, есть все еще проблема с этим подходом. Рассмотрите, например, что происходит, если мы неоднократно ставим в очередь и dequeue единственный элемент N различные времена. У нас был бы f = r = N. Если бы мы должны были тогда попытаться вставить элемент просто еще раз, мы получили бы множество за пределы ошибка, даже при том, что есть много комнаты в очереди в этом случае. Чтобы избежать этой проблемы и быть в состоянии использовать все множество Q, мы позволяем f и r индексам «обертка вокруг» конца Q.

Таким образом, мы теперь рассматриваем Q как «круглое множество», которое идет от Q [0] к Q [N- 1] и

тогда немедленно назад к Q [0] снова. (См. рисунок 5.4.)

012

f

(a)

r

N-1

012

r

(b)

f

N-1

Рисунок 5.4: Используя множество Q круглым способом: (a) «нормальная» конфигурация с

f£ r; (b) «обернутый вокруг» конфигурации с r <f. Очередь хранения клеток

элементы заштрихованы.

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

Осуществление этого круглого представления о Q фактически довольно легко. Каждый раз мы в - crement f или r, мы просто должны вычислить это приращение как» (f + 1) модник Н» или» (r + 1) модник Н», соответственно, где оператор «модник» является модулем oper-ator. Этот оператор вычислен для положительного числа, беря остаток после составного подразделения. Например, 48 разделенных 5 9 с остатком 3,

так 48 модников 5 = 3. Определенно, данный целые числа x и y, такой, что x³ 0 и y> 0,

x ультрасовременный y уникальное целое число0£ r <y таким образом что x = qy + r, для некоторого целого числа q.

Вспомните, что C ++ использует «%», чтобы обозначить оператора модуля.

Мы представляем наше внедрение в Кодовом Фрагменте 5.17. Обратите внимание на то, что мы ввели новое исключение, названное QueueFull, чтобы сигнализировать, что больше элементов не может быть вставлено в очередь. Наше внедрение очереди посредством множества подобно тому из стека и оставлено как осуществление.

Основанное на множестве внедрение очереди довольно эффективно. Все операции очереди ADT выполнены в O (1) время. Космическое использование - O (N), где N - размер множества, определенного в то время, когда очередь создана. Обратите внимание на то, что космическое использование независимо от номера n <N элементов, которые находятся фактически в очереди.

Как с основанным на множестве внедрением стека, единственный реальный недостаток основанного на множестве внедрения очереди - то, что мы искусственно устанавливаем возможность очереди быть некоторым номером N. В реальном применении нам, возможно, фактически понадобится более или менее способность очереди, чем это, но если у нас есть хорошая оценка числа