← Назад к вопросам

Для чего нужны Stack?

1.0 Junior🔥 191 комментариев
#Коллекции

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Для чего нужны Stack?

Stack (стек) — это одна из фундаментальных структур данных в информатике. Давайте разберёмся, что это такое и где его использовать.

Определение и принцип работы

Stack работает по принципу LIFO (Last In, First Out — последним пришёл, первым ушёл). Представьте стопку книг: вы кладёте книгу сверху и берёте книгу сверху.

import java.util.Stack;

Stack<String> stack = new Stack<>();

// push — добавить элемент
stack.push("First");
stack.push("Second");
stack.push("Third");

// pop — удалить и вернуть верхний элемент
String top = stack.pop();  // "Third"

// peek — посмотреть верхний элемент без удаления
String nextTop = stack.peek();  // "Second"

// empty — проверить, пуст ли стек
boolean isEmpty = stack.empty();  // false

Внутреннее устройство Stack в Java

Stack в Java наследуется от Vector (устаревший класс), поэтому лучше использовать Deque:

// Более современный подход
Deque<Integer> stack = new ArrayDeque<>();
stack.push(1);
stack.push(2);
int value = stack.pop();  // 2

Практические применения

1. Обратный порядок (Реверс)

Stack<Integer> stack = new Stack<>();
int[] arr = {1, 2, 3, 4, 5};

for (int num : arr) {
    stack.push(num);
}

while (!stack.empty()) {
    System.out.print(stack.pop() + " ");  // 5 4 3 2 1
}

2. Проверка сбалансированных скобок

public boolean isBalanced(String expression) {
    Stack<Character> stack = new Stack<>();
    
    for (char ch : expression.toCharArray()) {
        if (ch == '(' || ch == '{' || ch == '[') {
            stack.push(ch);
        } else if (ch == ')' || ch == '}' || ch == ']') {
            if (stack.empty()) return false;
            char top = stack.pop();
            if (!matches(top, ch)) return false;
        }
    }
    
    return stack.empty();
}

private boolean matches(char open, char close) {
    return (open == '(' && close == ')') ||
           (open == '{' && close == '}') ||
           (open == '[' && close == ']');
}

// Использование
isBalanced("({[]})");  // true
isBalanced("({[}])");  // false

3. Вычисление обратной польской нотации (RPN)

public int evaluateRPN(String[] tokens) {
    Stack<Integer> stack = new Stack<>();
    
    for (String token : tokens) {
        if (isOperator(token)) {
            int b = stack.pop();
            int a = stack.pop();
            stack.push(calculate(a, b, token));
        } else {
            stack.push(Integer.parseInt(token));
        }
    }
    
    return stack.pop();
}

private int calculate(int a, int b, String op) {
    return switch(op) {
        case "+" -> a + b;
        case "-" -> a - b;
        case "*" -> a * b;
        case "/" -> a / b;
        default -> 0;
    };
}

4. Отмена операций (Undo)

public class TextEditor {
    private StringBuilder text = new StringBuilder();
    private Stack<String> history = new Stack<>();
    
    public void type(String input) {
        history.push(text.toString());
        text.append(input);
    }
    
    public void undo() {
        if (!history.empty()) {
            text = new StringBuilder(history.pop());
        }
    }
}

5. Обход графа (DFS)

public void depthFirstSearch(Node startNode) {
    Stack<Node> stack = new Stack<>();
    Set<Node> visited = new HashSet<>();
    
    stack.push(startNode);
    
    while (!stack.empty()) {
        Node current = stack.pop();
        
        if (visited.contains(current)) continue;
        visited.add(current);
        
        System.out.println(current.value);
        
        for (Node neighbor : current.neighbors) {
            if (!visited.contains(neighbor)) {
                stack.push(neighbor);
            }
        }
    }
}

6. Парсинг и компиляция

Stack используется в компиляторах для разбора синтаксиса языков, управления вложенностью блоков кода и обработки вызовов функций.

Вызовы функций в Java

Каждый раз, когда функция вызывает другую функцию, создаётся frame в стеке вызовов. Это видно при StackOverflowError при бесконечной рекурсии — стек вызовов переполняется.

Производительность

Operations на Stack имеют O(1) амортизированную сложность: push, pop и peek работают за константное время.

Stack — это мощный инструмент для решения множества задач от реверса данных до сложного парсинга кода.