En este tema, aprenderemos cómo implementar una pila (stack) en diferentes lenguajes de programación. Una pila es una estructura de datos que sigue el principio LIFO (Last In, First Out), donde el último elemento en entrar es el primero en salir. Vamos a cubrir los siguientes puntos:

  1. Conceptos Básicos de Pilas
  2. Implementación de Pilas en Python
  3. Implementación de Pilas en Java
  4. Implementación de Pilas en C++
  5. Ejercicios Prácticos

  1. Conceptos Básicos de Pilas

Antes de entrar en la implementación, repasemos los conceptos básicos de una pila:

  • Push: Añadir un elemento a la pila.
  • Pop: Eliminar el elemento superior de la pila.
  • Peek/Top: Obtener el elemento superior sin eliminarlo.
  • isEmpty: Verificar si la pila está vacía.

  1. Implementación de Pilas en Python

En Python, podemos implementar una pila utilizando una lista. Aquí está el código:

class Stack:
    def __init__(self):
        self.stack = []

    def push(self, item):
        self.stack.append(item)
        print(f"Pushed {item} to stack")

    def pop(self):
        if not self.is_empty():
            item = self.stack.pop()
            print(f"Popped {item} from stack")
            return item
        else:
            print("Stack is empty")
            return None

    def peek(self):
        if not self.is_empty():
            return self.stack[-1]
        else:
            print("Stack is empty")
            return None

    def is_empty(self):
        return len(self.stack) == 0

    def size(self):
        return len(self.stack)

# Ejemplo de uso
stack = Stack()
stack.push(10)
stack.push(20)
print("Top element:", stack.peek())
stack.pop()
print("Stack size:", stack.size())

Explicación del Código

  • __init__: Inicializa una lista vacía para la pila.
  • push: Añade un elemento al final de la lista.
  • pop: Elimina y devuelve el último elemento de la lista.
  • peek: Devuelve el último elemento sin eliminarlo.
  • is_empty: Verifica si la lista está vacía.
  • size: Devuelve el tamaño de la pila.

  1. Implementación de Pilas en Java

En Java, podemos implementar una pila utilizando la clase ArrayList. Aquí está el código:

import java.util.ArrayList;

class Stack {
    private ArrayList<Integer> stack;

    public Stack() {
        stack = new ArrayList<>();
    }

    public void push(int item) {
        stack.add(item);
        System.out.println("Pushed " + item + " to stack");
    }

    public Integer pop() {
        if (!isEmpty()) {
            int item = stack.remove(stack.size() - 1);
            System.out.println("Popped " + item + " from stack");
            return item;
        } else {
            System.out.println("Stack is empty");
            return null;
        }
    }

    public Integer peek() {
        if (!isEmpty()) {
            return stack.get(stack.size() - 1);
        } else {
            System.out.println("Stack is empty");
            return null;
        }
    }

    public boolean isEmpty() {
        return stack.isEmpty();
    }

    public int size() {
        return stack.size();
    }

    public static void main(String[] args) {
        Stack stack = new Stack();
        stack.push(10);
        stack.push(20);
        System.out.println("Top element: " + stack.peek());
        stack.pop();
        System.out.println("Stack size: " + stack.size());
    }
}

Explicación del Código

  • Stack: Inicializa un ArrayList para la pila.
  • push: Añade un elemento al final del ArrayList.
  • pop: Elimina y devuelve el último elemento del ArrayList.
  • peek: Devuelve el último elemento sin eliminarlo.
  • isEmpty: Verifica si el ArrayList está vacío.
  • size: Devuelve el tamaño de la pila.

  1. Implementación de Pilas en C++

En C++, podemos implementar una pila utilizando la clase vector. Aquí está el código:

#include <iostream>
#include <vector>

class Stack {
private:
    std::vector<int> stack;

public:
    void push(int item) {
        stack.push_back(item);
        std::cout << "Pushed " << item << " to stack" << std::endl;
    }

    int pop() {
        if (!isEmpty()) {
            int item = stack.back();
            stack.pop_back();
            std::cout << "Popped " << item << " from stack" << std::endl;
            return item;
        } else {
            std::cout << "Stack is empty" << std::endl;
            return -1;
        }
    }

    int peek() {
        if (!isEmpty()) {
            return stack.back();
        } else {
            std::cout << "Stack is empty" << std::endl;
            return -1;
        }
    }

    bool isEmpty() {
        return stack.empty();
    }

    int size() {
        return stack.size();
    }
};

int main() {
    Stack stack;
    stack.push(10);
    stack.push(20);
    std::cout << "Top element: " << stack.peek() << std::endl;
    stack.pop();
    std::cout << "Stack size: " << stack.size() << std::endl;
    return 0;
}

Explicación del Código

  • Stack: Inicializa un vector para la pila.
  • push: Añade un elemento al final del vector.
  • pop: Elimina y devuelve el último elemento del vector.
  • peek: Devuelve el último elemento sin eliminarlo.
  • isEmpty: Verifica si el vector está vacío.
  • size: Devuelve el tamaño de la pila.

  1. Ejercicios Prácticos

Ejercicio 1: Implementar una Pila de Cadenas

Implementa una pila que almacene cadenas en lugar de enteros. Realiza las operaciones básicas (push, pop, peek, isEmpty, size) y prueba tu implementación.

Ejercicio 2: Verificar Balanceo de Paréntesis

Escribe una función que use una pila para verificar si los paréntesis en una expresión están balanceados. Por ejemplo, la expresión "(a + b) * (c - d)" está balanceada, mientras que "(a + b * (c - d)" no lo está.

Soluciones

Ejercicio 1: Implementar una Pila de Cadenas (Python)

class StringStack:
    def __init__(self):
        self.stack = []

    def push(self, item):
        self.stack.append(item)
        print(f"Pushed {item} to stack")

    def pop(self):
        if not self.is_empty():
            item = self.stack.pop()
            print(f"Popped {item} from stack")
            return item
        else:
            print("Stack is empty")
            return None

    def peek(self):
        if not self.is_empty():
            return self.stack[-1]
        else:
            print("Stack is empty")
            return None

    def is_empty(self):
        return len(self.stack) == 0

    def size(self):
        return len(self.stack)

# Ejemplo de uso
stack = StringStack()
stack.push("hello")
stack.push("world")
print("Top element:", stack.peek())
stack.pop()
print("Stack size:", stack.size())

Ejercicio 2: Verificar Balanceo de Paréntesis (Python)

def is_balanced(expression):
    stack = Stack()
    for char in expression:
        if char == '(':
            stack.push(char)
        elif char == ')':
            if stack.is_empty():
                return False
            stack.pop()
    return stack.is_empty()

# Ejemplo de uso
expression = "(a + b) * (c - d)"
print(f"Is the expression '{expression}' balanced? {is_balanced(expression)}")

Conclusión

En esta sección, hemos aprendido cómo implementar una pila en diferentes lenguajes de programación y hemos practicado con ejercicios para reforzar los conceptos. La implementación de pilas es fundamental para entender cómo funcionan muchas aplicaciones y algoritmos en informática. En el próximo módulo, exploraremos las colas, otra estructura de datos esencial.

© Copyright 2024. Todos los derechos reservados