5.5 Упражнения¶
5.5.1 Вопросы для самопроверки¶
1. Что первым извлекается из стека и очереди¶
Подготовьте пустой стек S и пустую очередь Q, а затем выполните с каждым из них один и тот же набор операций:
шаг 1: добавить A;
шаг 2: добавить B;
шаг 3: удалить один элемент и записать его;
шаг 4: добавить C;
шаг 5: удалять и записывать элементы, пока контейнер не опустеет.
Запишите порядок удаления элементов из S и Q. Объясните различие принципами «последним пришел — первым вышел» и «первым пришел — первым вышел».
Ответ
Порядок удаления из стека S: B, C, A. После добавления A, B первым извлекается последний добавленный элемент B; затем добавляется C,
после чего извлекаются C, A. Это принцип «последним пришел — первым вышел».
Порядок удаления из очереди Q: A, B, C. После добавления A, B первым удаляется самый ранний элемент A;
затем добавляется C, после чего удаляются B, C. Это принцип «первым пришел — первым вышел».
2. Что происходит, когда хвост очереди проходит конец массива¶
Очередь реализована с помощью кольцевого массива длины 5 с индексами 0–4.
Сейчас front = 3, size = 2, а элементы очереди A, B находятся по индексам 3 и 4 соответственно.
- По какому индексу нужно поместить
Cпри операции «добавитьCв очередь»? Чему после этого равноsize? - Затем из очереди удаляется один элемент. Какой именно? Чему равны новые значения
frontиsize? - Каков теперь логический порядок элементов от головы к хвосту очереди? Нужно ли при удалении сдвигать остальные элементы массива и почему?
Ответ
-
Позиция нового элемента равна
(front + size) % 5 = (3 + 2) % 5 = 0, поэтомуCпомещается по индексу 0. После добавленияsize = 3. -
Из очереди удаляется текущий первый элемент
A. Новый индекс головы равен(3 + 1) % 5 = 4, поэтомуfront = 4,size = 2. -
Логический порядок находящихся в очереди элементов —
B, C:Bнаходится по индексу 4, аC— по индексу 0. При удалении достаточно изменитьfrontиsize. Благодаря остатку от деления индекс в кольцевом массиве возвращается к началу, поэтому сдвигать вперед все остальные элементы не нужно.
3. Операции с обоих концов двусторонней очереди¶
Здесь push_first означает добавление в голову, push_last — добавление в хвост,
pop_first — извлечение из головы, а pop_last — извлечение из хвоста.
С пустой двусторонней очередью deq последовательно выполняются операции:
push_last(A)push_last(B)push_first(C)pop_last()push_last(D)pop_first()
- Какие элементы возвращают две операции извлечения?
- Какие элементы остаются после всех операций в порядке от головы к хвосту?
- Рассмотрите все 6 шагов. Можно ли выполнить их с обычной очередью, в которую разрешено добавлять только с хвоста, а удалять только с головы? Если нет, укажите недопустимые операции. Объясните также, может ли выполнить все шаги двусторонняя очередь и почему.
Ответ
После первых трех шагов двусторонняя очередь от головы к хвосту имеет вид [C, A, B].
-
pop_last()возвращаетB. После добавленияDочередь имеет вид[C, A, D], аpop_first()возвращаетC. -
В конце остаются
[A, D]. -
Обычная очередь, допускающая добавление с хвоста и удаление с головы, не может выполнить все операции: шаг 3
push_first(C)требует добавить элемент с головы, а шаг 4pop_last()— удалить элемент с хвоста. Обе операции выходят за рамки обычной очереди. Двусторонняя очередь позволяет добавлять и удалять элементы с обоих концов, поэтому может выполнить все 6 шагов.
5.5.2 Задачи по программированию¶
1. Проверка последовательности скобок¶
Дана строка s, содержащая только скобки трех видов: (), [], {}. С помощью стека определите, является ли последовательность правильной.
Правильная последовательность должна удовлетворять двум условиям: каждая закрывающая скобка соответствует по виду ближайшей еще не сопоставленной открывающей скобке, а после обхода не остается несопоставленных открывающих скобок. Верните логическое значение результата проверки.
Подсказки
- Можно создать отображение из закрывающей скобки в соответствующую открывающую
- Встретив закрывающую скобку, сначала проверьте, не пуст ли стек, а затем — совпадает ли его вершина
- После обхода стек также должен быть пуст