Что такое стек (Stack) как структура данных?

«Что такое стек (Stack) как структура данных?» — вопрос из категории Алгоритмы и структуры данных, который задают на 26% собеседований Node.js Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Стек (Stack) — это абстрактный тип данных, работающий по принципу LIFO (Last In, First Out): последний добавленный элемент извлекается первым. Основные операции: добавление (push) и удаление (pop) с вершины.

Реализация стека в JavaScript/Node.js:

class Stack {
  constructor() {
    this.items = [];
  }

  push(element) {
    this.items.push(element);
  }

  pop() {
    if (this.isEmpty()) {
      throw new Error('Stack is empty');
    }
    return this.items.pop();
  }

  peek() {
    if (this.isEmpty()) {
      return null;
    }
    return this.items[this.items.length - 1];
  }

  isEmpty() {
    return this.items.length === 0;
  }

  size() {
    return this.items.length;
  }
}

// Пример использования
const callStack = new Stack();
callStack.push('main()');
callStack.push('processOrder()');
callStack.push('validatePayment()');

console.log(callStack.peek()); // 'validatePayment()'
console.log(callStack.pop());  // 'validatePayment()' - удаляется
console.log(callStack.peek()); // 'processOrder()'

Практическое применение в разработке на Node.js:

  1. Call Stack: Сам JavaScript использует стек вызовов для отслеживания выполнения функций.
  2. Отмена операций (Undo):

    class TextEditor {
      constructor() {
        this.content = '';
        this.history = new Stack();
      }
    
      type(text) {
        this.history.push(this.content); // Сохраняем состояние
        this.content += text;
      }
    
      undo() {
        if (!this.history.isEmpty()) {
          this.content = this.history.pop(); // Восстанавливаем предыдущее состояние
        }
      }
    }
  3. Парсинг и валидация: Проверка корректности вложенных структур (например, JSON, HTML-тегов, скобок).

    function isBalancedParentheses(str) {
      const stack = new Stack();
      const pairs = { '(': ')', '[': ']', '{': '}' };
    
      for (let char of str) {
        if (pairs[char]) {
          stack.push(char); // Открывающая скобка -> в стек
        } else if (Object.values(pairs).includes(char)) {
          // Закрывающая скобка
          if (stack.isEmpty() || pairs[stack.pop()] !== char) {
            return false;
          }
        }
      }
      return stack.isEmpty(); // Все скобки должны быть закрыты
    }
    console.log(isBalancedParentheses('({[]})')); // true
    console.log(isBalancedParentheses('({[})'));  // false
  4. Маршрутизация и Middleware: Фреймворки вроде Express.js неявно используют стек для обработки цепочки middleware.