Cola (estructura de datos): definición, operaciones y colas de prioridad
Cola (estructura de datos): define encolar, desencolar, peek y colas de prioridad. Funcionamiento, ejemplos y aplicaciones prácticas en programación y algoritmos.
En informática, una cola es una estructura de datos, utilizada para almacenar elementos, antes de que sean procesados. Generalmente, existen las siguientes operaciones:
- Poner en cola: añadir el elemento a la parte posterior de la cola
- Dequeue: eliminar el elemento al frente de la cola
- Opcionalmente, puede haber una operación para mirar el elemento al frente de la cola, sin eliminarlo.
Los elementos que se encuentran entre el primer y el último elemento de la cola no son directamente accesibles.
Existe una especialización, denominada cola de prioridad: En una cola prioritaria, cada elemento tiene también un peso, que determina la posición del elemento en la cola.
Concepto y propiedades principales
Una cola tradicional sigue la disciplina FIFO (first-in, first-out): el primer elemento que entra es el primero que sale. Las operaciones más habituales reciben nombres como encolar (enqueue o poner en cola), desencolar (dequeue), y peek o front (consultar el elemento en el frente sin retirarlo).
Dos problemas típicos que deben manejar las implementaciones son:
- Underflow: intentar desencolar cuando la cola está vacía.
- Overflow: intentar encolar en una cola con capacidad limitada cuando está llena.
Operaciones y API común
- enqueue(item) / encolar: añade item al final de la cola.
- dequeue() / desencolar: elimina y devuelve el elemento al frente; puede lanzar error si está vacía.
- peek() / front(): devuelve el elemento del frente sin eliminarlo; útil para inspección.
- isEmpty(): indica si la cola está vacía.
- size(): devuelve el número de elementos actuales.
- En entornos concurrentes, también existen variaciones como blocking enqueue/dequeue (esperan hasta que puedan realizar la operación) y colas no bloqueantes o lock-free.
Implementaciones comunes
Las colas se pueden implementar de varias maneras, con ventajas y desventajas:
- Lista enlazada simple: mantener punteros al frente y a la cola. Encolar y desencolar en tiempo O(1) (sin copiar elementos), fácil crecimiento dinámico.
- Buffer circular (array circular o ring buffer): usar un array con índices front y rear que avanzan módulo la capacidad. Permite O(1) por operación y uso eficiente de memoria cuando la capacidad es conocida o limitada.
- Array dinámico: similar a un vector dinámico; encolar amortizado O(1) pero desencolar puede requerir mover índices o recompresión si no se usa anillo circular.
- Deques (colas doblemente terminadas): permiten insertar y eliminar por ambos extremos; son más generales que una cola simple.
- Colas concurrentes: implementaciones específicas para hilos múltiples (p. ej. colas bloqueantes, colas lock-free) que garantizan seguridad en entornos paralelos.
Complejidad temporal
- En estructuras bien implementadas (lista enlazada con punteros front/rear, buffer circular): enqueue y dequeue en O(1) en tiempo constante.
- En arrays dinámicos, encolar es O(1) amortizado; desencolar puede seguir siendo O(1) si se mantiene un índice frontal, pero a largo plazo hay que controlar el uso de memoria.
- Colas de prioridad (ver más abajo): operaciones típicas en O(log n) con montículos binarios.
Variantes y extensiones
- Cola circular: evita el desplazamiento de elementos usando índices modulares; muy usada en sistemas embebidos y comunicaciones.
- Cola doble (deque): inserción y eliminación por ambos extremos.
- Colas acotadas vs. no acotadas: una cola acotada tiene capacidad máxima; si es acotada y concurrente, a menudo proporciona operaciones bloqueantes o devuelve error si está llena.
- Colas de mensajes / colas en sistemas distribuidos: soportan persistencia, confirmaciones (acks), reintentos y garantías de orden según la implementación.
Colas de prioridad
Una cola de prioridad no sigue estrictamente FIFO: cada elemento tiene una prioridad (peso o clave) y la extracción devuelve el elemento con mayor prioridad (o menor, según la convención). Son útiles cuando el orden de servicio depende de un criterio adicional.
Implementaciones típicas:
- Montículo binario (binary heap): inserción y extracción en O(log n); implementación habitual y sencilla.
- Montículo de Fibonacci: inserción en O(1) amortizado y extracción en O(log n) amortizado; reduce el coste de decrease-key, útil en algoritmos como Dijkstra.
- Árboles equilibrados o colas con múltiples niveles: útiles cuando se necesitan operaciones adicionales o balances distintos.
Consideraciones prácticas: algunas colas de prioridad son estables (preservan el orden relativo de elementos con la misma prioridad) y otras no; elegir la implementación según requisitos de rendimiento y estabilidad.
Aplicaciones comunes
- Algoritmos de recorrido: BFS (breadth-first search) usa una cola FIFO.
- Gestión de tareas: planificadores, colas de impresión, servidores de trabajo (worker queues).
- Sistemas operativos y planificación de procesos: colas para diferentes niveles de prioridad.
- Comunicaciones y mensajería asíncrona: buffers de entrada/salida y colas de mensajes.
- Algoritmos de grafos y optimización: colas de prioridad para Dijkstra, Prim, etc.
Consideraciones prácticas
- Elegir la implementación según las restricciones: memoria limitada → buffer circular; operaciones frecuentes de inserción/eliminación → lista enlazada o anillo.
- En entornos multihilo, preferir implementaciones probadas y optimizadas (colas bloqueantes o lock-free) para evitar condiciones de carrera y cuellos de botella.
- Vigilar el manejo de errores (underflow/overflow) y las garantías de orden y durabilidad si la cola forma parte de un sistema distribuido o persistente.
En resumen, la cola es una estructura simple pero fundamental con múltiples variantes y optimizaciones según el contexto: desde un buffer circular en tiempo real hasta una cola de prioridad eficiente para algoritmos de grafos.

Una cola
Buscar dentro de la enciclopedia