What is a stack in C++?

Guía Completa de la Pila (Stack) en C++ con STL

24/06/2022

Valoración: 4.65 (6247 votos)

En el vasto mundo de las estructuras de datos, pocas son tan intuitivas y fundamentales como la pila, o stack en inglés. Su principio de funcionamiento es algo que experimentamos en la vida cotidiana: al apilar platos, libros o cualquier otro objeto, el último que colocamos es siempre el primero que retiramos. Este concepto, conocido como LIFO (Last-In, First-Out), es la piedra angular de las pilas y tiene innumerables aplicaciones en la programación, desde la gestión de llamadas a funciones hasta algoritmos de búsqueda y análisis sintáctico. La Biblioteca de Plantillas Estándar (STL) de C++ nos ofrece una implementación robusta, eficiente y fácil de usar de esta estructura a través de la clase std::stack. En esta guía completa, desglosaremos todo lo que necesitas saber para utilizarla como un profesional.

How to use stack class in C++?
Following is the list of all member functions of std::stack class in C++: Add an element top of the stack. Add range of elements at top of the stack. Access the top element of the stack. Remove the top element of the stack. Add the constructs element in top of the stack. Returns the number of elements in the stack. Checks if the stack is empty.
Índice de Contenido

¿Qué es `std::stack` en la STL de C++?

La clase std::stack, definida en el archivo de cabecera <stack>, no es un contenedor en sí mismo, sino un adaptador de contenedor. Esto significa que actúa como una envoltura sobre un contenedor secuencial subyacente, restringiendo su interfaz para proporcionar únicamente la funcionalidad de una pila. En otras palabras, toma un contenedor como std::deque (el predeterminado), std::vector o std::list y lo adapta para que solo se pueda acceder a los elementos desde un extremo, conocido como la "cima" o "top" de la pila.

La sintaxis de su plantilla es la siguiente:

template <class T, class Container = std::deque<T>> class stack;
  • T: Representa el tipo de dato que se almacenará en la pila (por ejemplo, int, std::string, un objeto personalizado, etc.).
  • Container: Es el tipo de contenedor subyacente que se utilizará para almacenar los elementos. Debe cumplir ciertos requisitos, como proporcionar las funciones back(), push_back() y pop_back(). Por defecto, si no se especifica, C++ utiliza std::deque<T>, que ofrece un excelente equilibrio de rendimiento para las operaciones de una pila.

Operaciones Fundamentales con `std::stack`

La belleza de std::stack radica en su simplicidad. Ofrece un conjunto limitado pero potente de funciones miembro que encapsulan toda la lógica LIFO.

Insertar un elemento: `push()`

Para añadir un nuevo elemento a la pila, se utiliza el método push(). Este elemento se coloca en la cima de la pila, convirtiéndose en el nuevo elemento accesible a través de top().

#include <stack> std::stack<int> mi_pila; mi_pila.push(10); // La pila ahora contiene {10} mi_pila.push(20); // La pila ahora contiene {10, 20} (20 en la cima)

Acceder al elemento superior: `top()`

Para consultar el valor del elemento que se encuentra en la cima de la pila sin eliminarlo, se utiliza el método top(). Es importante destacar que llamar a top() en una pila vacía resulta en un comportamiento indefinido, por lo que siempre se debe verificar si la pila no está vacía antes de usarlo.

What is a stack in C++?
In C++ Standard Template Library (STL), a stack is a kind of container adapter declared in the 'stack' header file. It has some built-in functions which are used to perform stack operations. stack () - It is used to check whether the stack container is empty or not. size () - It returns the size (total number of elements in the stack) of the stack container.
int elemento_superior = mi_pila.top(); // elemento_superior será 20

Eliminar un elemento: `pop()`

El método pop() elimina el elemento que se encuentra en la cima de la pila. Es una función de tipo void, lo que significa que no devuelve el valor del elemento eliminado. Para obtener el valor y luego eliminarlo, necesitas llamar a top() primero y luego a pop().

mi_pila.pop(); // Elimina el 20. La pila ahora contiene {10}

Verificar si la pila está vacía: `empty()`

Esta función devuelve un valor booleano: true si la pila no contiene elementos y false en caso contrario. Es crucial para evitar errores al intentar acceder o eliminar elementos de una pila vacía.

if (!mi_pila.empty()) { // Es seguro usar top() y pop() }

Obtener el tamaño: `size()`

Devuelve el número de elementos que se encuentran actualmente en la pila.

size_t cantidad_elementos = mi_pila.size(); // devolverá 1

Ejemplo Práctico Completo en C++

Veamos cómo funcionan todas estas operaciones en un programa completo. Este código creará una pila de enteros, insertará varios elementos, mostrará su estado, eliminará algunos y volverá a mostrar el estado final.

#include <iostream> #include <stack> // Función auxiliar para mostrar el contenido de la pila sin modificar la original void mostrarPila(std::stack<int> st) { std::cout << "Contenido de la pila (de la cima a la base): "; while (!st.empty()) { std::cout << st.top() << " "; st.pop(); } std::cout << std::endl; } int main() { // Declaramos una pila de enteros std::stack<int> pila_numeros; // Insertamos elementos en la pila std::cout << "Insertando 10, 20, 30, 40, 50..." << std::endl; pila_numeros.push(10); pila_numeros.push(20); pila_numeros.push(30); pila_numeros.push(40); pila_numeros.push(50); // Mostramos el estado inicial de la pila std::cout << "Total de elementos en la pila: " << pila_numeros.size() << std::endl; std::cout << "Elemento en la cima: " << pila_numeros.top() << std::endl; mostrarPila(pila_numeros); std::cout << "\n--- Eliminando dos elementos ---" << std::endl; pila_numeros.pop(); // Elimina el 50 pila_numeros.pop(); // Elimina el 40 // Mostramos el estado final de la pila std::cout << "Total de elementos en la pila: " << pila_numeros.size() << std::endl; std::cout << "Nuevo elemento en la cima: " << pila_numeros.top() << std::endl; mostrarPila(pila_numeros); return 0; }

Salida del Programa:

Insertando 10, 20, 30, 40, 50... Total de elementos en la pila: 5 Elemento en la cima: 50 Contenido de la pila (de la cima a la base): 50 40 30 20 10 --- Eliminando dos elementos --- Total de elementos en la pila: 3 Nuevo elemento en la cima: 30 Contenido de la pila (de la cima a la base): 30 20 10 

Tabla Comparativa de Funciones

Para una referencia rápida, aquí tienes una tabla que resume las funciones más importantes de std::stack.

What is a stack class?
class T, class Container =std::deque< T > The std::stack class is a container adaptor that gives the programmer the functionality of a stack - specifically, a LIFO (last-in, first-out) data structure. The class template acts as a wrapper to the underlying container - only a specific set of functions is provided.
FunciónDescripciónSintaxis de Ejemplo
push(valor)Inserta un elemento en la cima de la pila.pila.push(100);
pop()Elimina el elemento de la cima de la pila. No devuelve nada.pila.pop();
top()Devuelve una referencia al elemento de la cima. No lo elimina.int cima = pila.top();
empty()Comprueba si la pila está vacía. Devuelve true o false.if (pila.empty()) { ... }
size()Devuelve el número de elementos en la pila.size_t tam = pila.size();

Rendimiento y Complejidad Temporal

Una de las grandes ventajas de usar std::stack es su eficiencia. Las operaciones fundamentales tienen una complejidad temporal constante, lo que las hace extremadamente rápidas, sin importar cuántos elementos haya en la pila.

OperaciónComplejidad Temporal
Insertar un elemento (push)O(1)
Eliminar un elemento (pop)O(1)
Acceder al elemento superior (top)O(1)
Recorrido (Pseudo-traversal)O(n)

Preguntas Frecuentes (FAQ)

¿Cuál es la diferencia entre `pop()` y `top()`?

Esta es una fuente común de confusión para los principiantes. La diferencia clave es que top() es una operación de "solo lectura": te permite ver cuál es el elemento en la cima sin modificar la pila. En cambio, pop() es una operación de "escritura": modifica la pila eliminando el elemento superior, pero no te dice cuál era ese elemento. Siempre debes usar top() para leer y pop() para eliminar.

¿Qué contenedor subyacente debería usar para mi pila?

Aunque std::deque es el predeterminado y generalmente la mejor opción, puedes especificar otros. std::vector puede ser ligeramente más eficiente en términos de memoria si el tamaño de la pila no cambia drásticamente, pero puede incurrir en costosas reasignaciones de memoria si crece mucho. std::list es una lista doblemente enlazada y puede ser una opción si realizas muchas inserciones y eliminaciones en pilas muy grandes, aunque tiene una mayor sobrecarga de memoria por elemento debido a los punteros.

¿Por qué no puedo iterar sobre una pila con un bucle `for`?

La restricción es intencional. El propósito de una pila es limitar el acceso solo al elemento superior para hacer cumplir estrictamente el principio LIFO. Permitir la iteración violaría este principio fundamental de la estructura de datos. Si necesitas acceder a todos los elementos, probablemente necesites un contenedor diferente, como un std::vector o std::list.

Si quieres conocer otros artículos parecidos a Guía Completa de la Pila (Stack) en C++ con STL puedes visitar la categoría Juegos.

Subir