7 - Operaciones fundamentales de una pila con listas enlazadas

API dinámica centrada en nodos

En una pila enlazada cada operación LIFO se reduce a reasignar referencias. No hay redimensionados ni desplazamientos: solo se mueve el puntero tope y, opcionalmente, un contador de longitud para consultas rápidas.

class Nodo:
  def __init__(self, valor, sig=None):
    self.valor = valor
    self.sig = sig


class PilaEnlazada:
  def __init__(self):
    self.tope = None
    self._largo = 0

  def __len__(self):
    return self._largo

  def esta_vacia(self):
    return self.tope is None

7.1 Push (apilar)

Crea un nuevo nodo y lo enlaza al tope actual. Complejidad O(1) y sin listas intermedias.

  def push(self, valor):
    self.tope = Nodo(valor, self.tope)
    self._largo += 1

7.2 Pop (desapilar)

Quita el nodo superior y devuelve su valor. Validar previamente que la pila no esté vacía evita accesos nulos.

  def pop(self):
    if self.esta_vacia():
      raise IndexError("Pila vacia")
    valor = self.tope.valor
    self.tope = self.tope.sig
    self._largo -= 1
    return valor

7.3 Peek

Permite leer el valor del tope sin quitarlo. Es útil para validaciones en parsers o backtracking.

  def peek(self):
    if self.esta_vacia():
      raise IndexError("Pila vacia")
    return self.tope.valor

7.4 Consultas y limpieza

Centralizar las comprobaciones evita repetir lógica y ayuda a mantener invariantes.

  def limpiar(self):
    self.tope = None
    self._largo = 0

  def imprimir(self):
    print(f"Pila enlazada ({len(self)} nodos):")
    actual = self.tope
    while actual:
      sufijo = " <- top" if actual is self.tope else ""
      print(f"  {actual.valor}{sufijo}")
      actual = actual.sig

limpiar deja la estructura lista para reutilizarse; imprimir facilita la depuración sin alterar el orden LIFO.

Código completo para usar o adaptar

El siguiente bloque combina toda la API en un script ejecutable:

class Nodo:
  def __init__(self, valor, sig=None):
    self.valor = valor
    self.sig = sig


class PilaEnlazada:
  def __init__(self):
    self.tope = None
    self._largo = 0

  def __len__(self):
    return self._largo

  def esta_vacia(self):
    return self.tope is None

  def push(self, valor):
    self.tope = Nodo(valor, self.tope)
    self._largo += 1

  def pop(self):
    if self.esta_vacia():
      raise IndexError("Pila vacia")
    valor = self.tope.valor
    self.tope = self.tope.sig
    self._largo -= 1
    return valor

  def peek(self):
    if self.esta_vacia():
      raise IndexError("Pila vacia")
    return self.tope.valor

  def limpiar(self):
    self.tope = None
    self._largo = 0

  def imprimir(self):
    print(f"Pila enlazada ({len(self)} nodos):")
    actual = self.tope
    while actual:
      sufijo = " <- top" if actual is self.tope else ""
      print(f"  {actual.valor}{sufijo}")
      actual = actual.sig


if __name__ == "__main__":
  pila = PilaEnlazada()

  for n in (2, 4, 6, 8):
    pila.push(n)
  pila.imprimir()

  print("Peek:", pila.peek())

  while not pila.esta_vacia():
    print("Pop:", pila.pop())

Ejecuta este código con python tema7_demo.py o prueba de inmediato en el editor online: