Узнайте, как создать очередь, когда единственной структурой данных, к которой у вас есть доступ, является стек.
Инструкции
Напишите функцию, которая создает очередь, используя два стека. Кроме этих двух стеков, вы не можете использовать никаких дополнительных структур данных в своей реализации. Она должна иметь методы enqueue, dequeue и s ize.
Не стесняйтесь изменять приведенный ниже код, когда начнете работу. Он предназначен для руководства.
Решение
1 class Queue {
2 constructor() {
3 this._enqueueStorage[];
4 this._dequeueStorage[];
5 }
6
7 enqueue(1tem) (
8 this. enqueuestorage.push(item); 9 }
10
11 dequeue( ) (
12 if(this. dequeueStorage.length) (
13 return this. dequeueStorage.pop();
14 }
15
16 1f(th1s ._enqueue5torage . 1ength) (
17 while(this. enqueue5torage.length) {
18 this. dequeuestorage.push(this. enqueue5torage.pop()); 19
20
21 return this. dequeueStorage.pop();
22
23
24 console.warn('Attempting to dequeue from an empty queue');
25 return undefined; 26
Как это работает
У нас есть два стека хранения, это ._enqueueStorage и
this .dequeuestorage. Чтобы увидеть, как они взаимодействуют, давайте рассмотрим пример.
Регистрация
Мы хотим поместить в очередь 5 элементов: 1, 2, 3, 4 и s. Мы ставим в очередь
и все они попадают в хранилище enqueuestorage.
enqueuestorage: [1, 2, 3, 4, 5] dequeuestorage: []
Теперь мы хотим выгрузить элемент. Давайте погрузимся в нашу функцию dequeue.
Декуирование
Мы пропускаем оператор if в строке 12, поскольку dequeuestorage пуст. Мы переходим
к строке 16.
Внутри этого if-выражения (строка 16) мы вытаскиваем каждый элемент из enqueuestorage и помещаем его в dequeuestorage. Когда цикл while-loop (строки 17-19) завершен, enqueuestorage пуст, а dequeuestorage содержит пять элементов, но в обратном порядке.
enqueuestorage: [) dequeuestorage: [5, 4, 3, 2, 1]
В строке 21 мы открываем dequeuestorage и возвращаем элемент, i.
enqueuestorage: [] dequeuestorage: [5, 4, 3, 2]
Если мы хотим снова выполнить dequeuue, мы можем войти в метод dequeuue еще раз. На этот раз мы заходим в первое if-выражение, берем элемент из dequeuestorage и возвращаем его.
enqueuestorage: [] dequeuestorage: [5, 4, 3]
Мы можем продолжать декуизацию, если захотим. Пока в dequeuestorage есть элементы, последний элемент будет выгружен и возвращен нам.
Резюме
Все эти шаги вместе обеспечивают правильное функционирование нашей очереди. При постановке в очередь элементы помещаются в один стек. Выгрузка выгружает их из второго стека. Когда второй стек пуст и мы хотим снять очередь, мы сбрасываем первый стек на второй, меняя порядок элементов.
Время вызова
Каждое событие enqueue — это простое перемещение в стек. Это означает, что временная сложность каждого события enqueue составляет:
0(1)
Время выгрузки
Таким образом, для большинства случаев мы имеем o(1), а для редких случаев — o(n) Мы можем объединить их в одну временную сложность.
Жизненный цикл очереди
Давайте проследим за жизнью трех элементов в нашей очереди. Начиная с пустой очереди, давайте зачислим i, 2 и 3. Это поместит их в наш первый стек.
enqueuestorage: [1, 2, 3] dequeuestorage: []
Пока что мы выполнили 3 операции: поместили каждый из этих элементов в стек.
Давайте выгрузим все три элемента. Сначала все элементы из хранилища enqueuestorage
переносятся в хранилище dequeuestorage.
enqueuestorage: [] dequeuestorage: [1, 2, 3]
Будем считать, что перенос — это 1 операция. Это еще 3 операции, итого 6.