En este pequeño artículo, vamos a ver que son estos conceptos de cola y de pila y no, no me refiero al significado de la cola de un animal ni a una pila como las usadas en el mando de la tele 😝
El concepto de cola (FIFO) y pila (LIFO), en el mundo de la programación, se aplican a las estructuras de datos.
Veámoslo más detenidamente y verás que fácil 😉
FIFO (First In, First Out)
El significado es “el primero en entrar, es el primero en salir”. Y… “la traducción” por así decirlo, en español viene a ser como “una cola”; Una cola de un supermercado, por ejemplo. El primer cliente en llegar y ser atendido, es el primero en salir.
Por tanto, una cola no es un tipo de estructura de datos nueva, sino una implementación aplicada a una estructura de datos; útil, cuando necesitamos manejar procesos en orden de llegada. Por ejemplo, una lista de tareas, un sistema de notificaciones, una cola para imprimir documentos, gestionar un sistema de tickets o de soporte, etc.
Entonces, entendemos que una cola es ideal, en aquellas situaciones donde el orden de procesamiento debe respetar la secuencia de llegada.
Las operaciones que realizamos en una cola, se llaman: enqueue y dequeue.
- Enqueue: Añadir un elemento al final de la cola.
- Dequeue: Elimina y devuelve el elemento que está al principio de la cola.
from collections import deque # Simulación de una cola en un banco cola_banco = deque() # Llegan clientes al banco # Se aplica 'Enqueue': añadir elementos cola_banco.append("Cliente 1") cola_banco.append("Cliente 2") cola_banco.append("Cliente 3") print("Cola actual:", list(cola_banco)) # Se atiende al primer cliente que llegó # Se aplica 'Dequeue': eliminar el primer elemento atendido = cola_banco.popleft() print(f"Atendiendo a: {atendido}") print("Cola después de atender:", list(cola_banco))
LIFO (Last In, First Out)
Aquí, el significado es “el último elemento en entrar es el primero en salir”.
Podemos entenderlo como “una pila”; Una pila de platos, por ejemplo. Dónde el último plato colocado es el primero que se usa.
Las pilas, a diferencia de las colas, son útiles cuando necesitamos deshacer operaciones de una lista, procesar datos en orden inverso o al trabajar con algoritmos de recursión.
Un ejemplo típico, que usamos con frecuencia y que seguro no te has percatado, es la acción de “deshacer” de un editor de texto, de un programa de edición de imágenes o, incluso, el hecho de retroceder en el navegador.
Un ejemplo (similar a la pila de platos) es cuando guardamos libros en una caja. Imagina que estamos haciendo una mudanza y en una caja guardas algunos libros. Pues bien, el último libro que colocaste, será el primero que saques.
# Simulación de una pila con libros pila_libros = [] # Guardamos libros en la caja pila_libros.append("Harry Potter (de J.K. Rowling)") pila_libros.append("El Señor de los Anillos (J.R.R. Tolkien)") pila_libros.append("El Código da Vinci (de Dan Brown)") pila_libros.append("El diario de Ana Frank (de Anna Frank)") print("Pila actual:", pila_libros) # Sacamos el último libro que guardamos ultimo = pila_libros.pop() print(f"Sacando: {ultimo}") print("Pila después de sacar un libro de la caja:", pila_libros)
Concluyendo…
Como nota final, si te has fijado, hay una diferencia importante en el código y es que, en las colas FIFO, debemos de usar “deque” debido a que, en una cola, los elementos se agregan al final y se eliminan del principio. Si usáramos una lista normal (list), con el método “.pop(0)”, se eliminaría el primer elemento, pero esto sería ineficiente, porque todos los elementos restantes deben desplazarse una posición. Es decir, si tenemos una cola como la siguiente y usáramos una lista:
cola = [] cola.append("A") cola.append("B") cola.append("C") cola.pop(0)
cola.pop(0) elimina el primer elemento, pero es lento porque mueve todos los elementos una posición a la izquierda (O(n)).
Entonces, la solución es usar deque porque está optimizado para eliminar elementos del principio de la estructura en tiempo constante, lo que lo hace mucho más rápido para colas.
Resumiendo, deque.popleft() es más eficiente que list.pop(0).
Y en las pilas LIFO, sucede lo contrario, es decir, no necesitamos usar deque en pilas porque .pop() en listas ya es eficiente. Las listas (list) funcionan bien para pilas (LIFO) porque no requieren eliminar nada del principio, solo del final.
Nada, solo quería aclararlo un poco 😉
Y ahora ya si para acabar, recuerda que, si necesitas procesar datos en orden inverso, una pila es la mejor opción. Si necesitas respetar el orden de llegada, una cola es la solución adecuada.
Sobre el autor
Este artículo está publicado bajo una licencia Creative Commons Atribución-CompartirIgual 4.0 Internacional . Puedes compartirlo y adaptarlo, incluso con fines comerciales, siempre que cites al autor y mantengas esta misma licencia.