Translate

martes, 17 de diciembre de 2024

Colas en Erlang

 


El módulo de queue implementa una cola FIFO (First In, First Out) de dos extremos.

El módulo de queue básicamente tiene diferentes funciones en una separación mental en 3 interfaces (o API) de complejidad variable, llamadas API original, API extendida y API de Okasaki:

La API original contiene las funciones en la base del concepto de colas, incluyendo: new/0, para crear colas vacías, in/2, para insertar nuevos elementos, out/1, para eliminar elementos, y luego funciones para convertir a listas, invertir la cola, ver si un valor particular es parte de ella, etc.

La API extendida principalmente agrega algo de poder de introspección y flexibilidad: le permite hacer cosas como mirar el frente de la cola sin eliminar el primer elemento (ver get/1 o peek/1), eliminar elementos sin preocuparse por ellos (drop/1), etc. Estas funciones no son esenciales para el concepto de colas, pero aún así son útiles en general.

La API de Okasaki es un poco rara. Se deriva de las estructuras de datos puramente funcionales de Chris Okasaki. La API proporciona operaciones similares a las que estaban disponibles en las dos API anteriores, pero algunos de los nombres de las funciones están escritos al revés y todo el asunto es relativamente peculiar. A menos que sepas que quieres esta API, no me molestaría en usarla.

Generalmente querrás usar colas cuando necesites asegurarte de que el primer elemento ordenado sea de hecho el primero en procesarse.

veamos un ejemplo: 

-module(queue_demo).

-export([demo/0]).


demo() ->

    % Crear una cola vacía

    Q0 = queue:new(),

    io:format("Cola inicial: ~p~n", [Q0]),


    % Agregar elementos a la cola

    Q1 = queue:in(1, Q0),

    Q2 = queue:in(2, Q1),

    Q3 = queue:in(3, Q2),

    io:format("Cola después de agregar elementos: ~p~n", [Q3]),


    % Sacar un elemento de la cola

    {ok, Element, Q4} = queue:out(Q3),

    io:format("Elemento removido: ~p~n", [Element]),

    io:format("Cola después de remover un elemento: ~p~n", [Q4]),


    % Revisar el elemento al frente sin sacarlo

    {value, PeekElement} = queue:peek(Q4),

    io:format("Elemento al frente de la cola: ~p~n", [PeekElement]),


    % Verificar si la cola está vacía

    IsEmpty = queue:is_empty(Q4),

    io:format("¿La cola está vacía? ~p~n", [IsEmpty]),


    % Obtener el tamaño de la cola

    QueueSize = queue:len(Q4),

    io:format("Tamaño de la cola: ~p~n", [QueueSize]),


    % Convertir la cola a una lista

    ListRepresentation = queue:to_list(Q4),

    io:format("Cola como lista: ~p~n", [ListRepresentation]),


    % Agregar un elemento al frente de la cola

    Q5 = queue:in_r(0, Q4),

    io:format("Cola después de agregar al frente: ~p~n", [Q5]).


Y si ejecutamos esto vamos a tener este resultado: 

Cola inicial: {[], []}
Cola después de agregar elementos: {[], [3,2,1]}
Elemento removido: 1
Cola después de remover un elemento: {[], [3,2]}
Elemento al frente de la cola: 2
¿La cola está vacía? false
Tamaño de la cola: 2
Cola como lista: [2,3]
Cola después de agregar al frente: {[0], [3,2]}