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

Приведи пример стека

2.0 Middle🔥 171 комментариев
#Python Core

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

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

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

Стек (Stack) в Python: определение и примеры

Стек — это линейная структура данных, которая следует принципу LIFO (Last In, First Out). Это означает, что последний добавленный элемент — первый удаляемый. Представьте стопку тарелок: вы кладете тарелку сверху и берете со слуга же места.

Основные операции стека

  • push() — добавить элемент на вершину стека
  • pop() — удалить и вернуть элемент с вершины
  • peek() — посмотреть верхний элемент без удаления
  • isEmpty() — проверить, пуст ли стек
  • size() — получить количество элементов

Пример 1: Реализация стека на базе списка

class Stack:
    def __init__(self):
        self.items = []
    
    def push(self, item):
        """Добавить элемент на вершину стека"""
        self.items.append(item)
    
    def pop(self):
        """Удалить и вернуть верхний элемент"""
        if not self.is_empty():
            return self.items.pop()
        return None
    
    def peek(self):
        """Посмотреть верхний элемент без удаления"""
        if not self.is_empty():
            return self.items[-1]
        return None
    
    def is_empty(self):
        """Проверить, пуст ли стек"""
        return len(self.items) == 0
    
    def size(self):
        """Получить размер стека"""
        return len(self.items)
    
    def __str__(self):
        return str(self.items)

# Использование
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)

print(f"Стек: {stack}")  # [1, 2, 3]
print(f"Верхний элемент: {stack.peek()}")  # 3
print(f"Размер: {stack.size()}")  # 3

print(f"Удален: {stack.pop()}")  # 3
print(f"Удален: {stack.pop()}")  # 2
print(f"Стек: {stack}")  # [1]

Пример 2: Использование встроенного списка Python

Python списки имеют методы append() и pop(), которые работают как push/pop:

stack = []

# push — добавить элемент
stack.append("a")
stack.append("b")
stack.append("c")

print(stack)  # ['a', 'b', 'c']

# pop — удалить верхний элемент
print(stack.pop())  # 'c'
print(stack.pop())  # 'b'
print(stack)  # ['a']

# peek — посмотреть верхний элемент
if stack:
    print(stack[-1])  # 'a'

Пример 3: Проверка сбалансированности скобок (классическая задача)

class Stack:
    def __init__(self):
        self.items = []
    
    def push(self, item):
        self.items.append(item)
    
    def pop(self):
        return self.items.pop() if not self.is_empty() else None
    
    def is_empty(self):
        return len(self.items) == 0

def is_balanced(expression):
    """Проверить, сбалансированы ли скобки"""
    stack = Stack()
    opening = {"(", "[", "{"}
    closing = {")": "(", "]": "[", "}": "{"}
    
    for char in expression:
        if char in opening:
            stack.push(char)
        elif char in closing:
            if stack.is_empty() or stack.pop() != closing[char]:
                return False
    
    return stack.is_empty()

# Примеры
print(is_balanced("(())"))      # True
print(is_balanced("([{}])"))    # True
print(is_balanced("([)]"))      # False
print(is_balanced("((("))       # False
print(is_balanced("())"))       # False

Пример 4: Реверс строки с использованием стека

def reverse_string(s):
    """Развернуть строку используя стек"""
    stack = []
    
    # Пушим каждый символ
    for char in s:
        stack.append(char)
    
    # Попим в обратном порядке
    reversed_str = ""
    while stack:
        reversed_str += stack.pop()
    
    return reversed_str

print(reverse_string("hello"))   # olleh
print(reverse_string("python"))  # nohtyp

Пример 5: Обход истории браузера (назад/вперед)

class BrowserHistory:
    def __init__(self, homepage):
        self.back_stack = []  # История для кнопки "Назад"
        self.current = homepage
        self.forward_stack = []  # История для кнопки "Вперед"
    
    def visit(self, url):
        """Посетить новый сайт"""
        self.back_stack.append(self.current)
        self.current = url
        self.forward_stack = []  # Очищаем будущее при новом визите
    
    def back(self):
        """Вернуться на предыдущую страницу"""
        if self.back_stack:
            self.forward_stack.append(self.current)
            self.current = self.back_stack.pop()
        return self.current
    
    def forward(self):
        """Вперед на следующую страницу"""
        if self.forward_stack:
            self.back_stack.append(self.current)
            self.current = self.forward_stack.pop()
        return self.current
    
    def get_current(self):
        return self.current

# Использование
browser = BrowserHistory("google.com")
browser.visit("youtube.com")
browser.visit("github.com")
browser.visit("stackoverflow.com")

print(f"Текущая: {browser.get_current()}")  # stackoverflow.com
print(f"Назад: {browser.back()}")  # github.com
print(f"Назад: {browser.back()}")  # youtube.com
print(f"Вперед: {browser.forward()}")  # github.com
print(f"Вперед: {browser.forward()}")  # stackoverflow.com

Пример 6: Система отмены операций (Undo/Redo)

class TextEditor:
    def __init__(self):
        self.text = ""
        self.undo_stack = []  # История для отмены
        self.redo_stack = []  # История для повтора
    
    def type_text(self, new_text):
        """Добавить текст"""
        self.undo_stack.append(self.text)
        self.text += new_text
        self.redo_stack = []  # Очищаем redo при новом действии
        print(f"Текст: {self.text}")
    
    def undo(self):
        """Отменить последнее действие"""
        if self.undo_stack:
            self.redo_stack.append(self.text)
            self.text = self.undo_stack.pop()
            print(f"После отмены: {self.text}")
    
    def redo(self):
        """Повторить отмененное действие"""
        if self.redo_stack:
            self.undo_stack.append(self.text)
            self.text = self.redo_stack.pop()
            print(f"После повтора: {self.text}")

# Использование
editor = TextEditor()
editor.type_text("Hello")  # Hello
editor.type_text(" World")  # Hello World
editor.undo()  # Hello
editor.undo()  # 
editor.redo()  # Hello
editor.redo()  # Hello World

Пример 7: Вычисление выражений в обратной польской нотации

def evaluate_rpn(tokens):
    """Вычислить выражение в обратной польской нотации
    Пример: ["2", "1", "+", "3", "*"] → 9 (то есть (2+1)*3)
    """
    stack = []
    operators = {"+", "-", "*", "/"}
    
    for token in tokens:
        if token in operators:
            # Вычисляем операцию с двумя верхними элементами
            b = stack.pop()
            a = stack.pop()
            
            if token == "+":
                result = a + b
            elif token == "-":
                result = a - b
            elif token == "*":
                result = a * b
            elif token == "/":
                result = int(a / b)
            
            stack.append(result)
        else:
            # Число
            stack.append(int(token))
    
    return stack[0]

print(evaluate_rpn(["2", "1", "+", "3", "*"]))  # 9
print(evaluate_rpn(["4", "13", "5", "/", "+"]))  # 6
print(evaluate_rpn(["10", "6", "9", "3", "/", "/", "-", "2", "*", "2", "+", "*"]))  # 36

Пример 8: Использование модуля collections.deque (оптимизированный стек)

from collections import deque

stack = deque()

# push
stack.append(1)
stack.append(2)
stack.append(3)

# pop (очень эффективно)
print(stack.pop())  # 3
print(stack.pop())  # 2

# peek
if stack:
    print(stack[-1])  # 1

print(len(stack))  # 1

Сложность операций

Операция     | Сложность
------------ | ---------
push()       | O(1)
pop()        | O(1)
peek()       | O(1)
is_empty()   | O(1)
size()       | O(1)
поиск элемента | O(n)

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

  • Парсинг выражений — проверка скобок, вычисление RPN
  • Отмена операций — undo/redo в редакторах
  • Навигация — история браузера, back button
  • Вызовы функций — call stack в интерпретаторе
  • Обход графов — DFS (глубинный поиск)
  • Обработка JSON — парсинг вложенных структур

Вывод

Стек — фундаментальная структура данных, которая использует принцип LIFO. Python предоставляет несколько способов реализации стека: от простых списков до оптимизированного deque. Понимание стеков критически важно для решения задач по парсингу, отмене операций и навигации.