Эта статья посвящена реализации структуры данных стека в javascript с нуля.
Полный код приведен в конце статьи. Сначала мы упростим все операции со стеком до небольших лаконичных функций, а затем объединим все функции в конце.
Что такое стек?
Стек — это тип структуры данных, который следует принципу LIFO — Last In First Out.
Элемент, добавленный в стек последним, будет удален первым.
Мы можем думать о куче чего угодно как о примере стека. Стопка книг, поставленных друг на друга. Чтобы добавить еще одну книгу, мы добавляем ее в верхнюю часть стопки, а чтобы удалить одну, делаем то же самое. Последняя книга, которую мы добавим, будет первой книгой, которая будет удалена.
Стеки обычно используются для функций отмены и повтора.
Мы будем реализовывать стек с нуля, используя односвязный список.
Мы должны иметь возможность инициализировать стек с помощью
const stack = new Stack();
и мы должны иметь возможность хранить в нем данные.
Давайте сначала начнем с создания класса стека
class Stack {
constructor(){
this.first = null;
this.last = null;
this.size = 0;
}
}
Объяснение. В начале первый и последний элементы стека равны нулю, и размер стека также равен нулю.
Далее давайте определим класс для каждого узла стека.
class Node {
constructor(value){
this.value = value;
this.next = null;
}
}
Объяснение. Приведенный выше узел будет хранить часть данных в this.value и ссылаться на следующий узел в this.next.
Теперь, двигаясь дальше, в стеке push и pop являются постоянными, так как мы добавляем или удаляем последний вставленный элемент в стеке.
Реализация Push() для стека
Для помещения в стек нам нужно позаботиться о следующих случаях:
- Принять значение для вставки
- создать узел для значения
- если в стеке нет узлов, вновь созданный узел становится первым и последним.
- если узлы уже существуют, вновь созданный узел становится первым, а его следующий указывает на предыдущий узел.
- следить за размером стека
push(val){
var newNode = new Node(val);
<!-- if there are no nodes in the stack -->
if(!this.first){
this.first = newNode;
this.last = newNode;
}else {
<!-- if the stack already has nodes -->
var temp = this.first;
this.first = newNode;
this.first.next = temp;
}
<!-- keeping track of size -->
return ++this.size;
}
Реализация Pop() для стека
Случаи, которые нам необходимо рассмотреть
- если стек пуст, вернуть ноль
- если есть только один узел, первый и последний станут нулевыми после того, как мы удалим узел
- если более 1 узла, текущий первый -> следующий становится первым
- следить за размером стека
pop(){ <!-- if no nodes in the stack --> if(!this.first){ return null; } let temp = this.first;
<!-- If only one node --> if(this.first === this.last){ this.last = null; } <!-- if more than one node --> this.first = this.first.next; this.size--;
return temp; }
Полный код для реализации стека в JS
class Node { constructor(value){ this.value = value; this.next = null; } } class Stack { constructor(){ this.first = null; this.last = null; this.size = 0; } push(val){ var newNode = new Node(val); if(!this.first){ this.first = newNode; this.last = newNode; }else { var temp = this.first; this.first = newNode; this.first.next = temp; } return ++this.size; }
pop(){ if(!this.first) return null; var temp = this.first; if(this.first === this.last){ this.last = null; } this.first = this.first.next; this.size--; return temp.value; } }
var stack = new Stack(); console.log(stack.push(10)); console.log(stack.push(40)); console.log(stack.push(411)); console.log(stack.push(50)); console.log(stack.pop()); console.log(stack.pop());