Current section
Files
Jump to
Current section
Files
src/gleamy@structures@heap@pairing_heap.erl
-module(gleamy@structures@heap@pairing_heap).
-compile([no_auto_import, nowarn_unused_vars]).
-export([new/1, find_min/1, insert/2, delete_min/1]).
-export_type([t/1, heap/1]).
-type t(GNC) :: e | {t, GNC, list(t(GNC))}.
-opaque heap(GND) :: {heap, t(GND), fun((GND, GND) -> gleam@order:order())}.
-spec new(fun((GNE, GNE) -> gleam@order:order())) -> heap(GNE).
new(Compare) ->
{heap, e, Compare}.
-spec find_min(heap(GNJ)) -> {ok, GNJ} | {error, nil}.
find_min(Heap) ->
case erlang:element(2, Heap) of
{t, X, _} ->
{ok, X};
e ->
{error, nil}
end.
-spec merge(t(GNS), t(GNS), fun((GNS, GNS) -> gleam@order:order())) -> t(GNS).
merge(X, Y, Compare) ->
case {X, Y} of
{X@1, e} ->
X@1;
{e, Y@1} ->
Y@1;
{{t, Xk, Xs}, {t, Yk, Ys}} ->
case Compare(Xk, Yk) of
gt ->
{t, Yk, [X | Ys]};
_ ->
{t, Xk, [Y | Xs]}
end
end.
-spec insert(heap(GNG), GNG) -> heap(GNG).
insert(Heap, Key) ->
{heap,
merge({t, Key, []}, erlang:element(2, Heap), erlang:element(3, Heap)),
erlang:element(3, Heap)}.
-spec merge_pairs(list(t(GNW)), fun((GNW, GNW) -> gleam@order:order())) -> t(GNW).
merge_pairs(L, Compare) ->
case L of
[] ->
e;
[H] ->
H;
[H1, H2 | Hs] ->
merge(merge(H1, H2, Compare), merge_pairs(Hs, Compare), Compare)
end.
-spec delete_min(heap(GNN)) -> {ok, {GNN, heap(GNN)}} | {error, nil}.
delete_min(Heap) ->
case erlang:element(2, Heap) of
{t, X, Xs} ->
{ok,
{X,
{heap,
merge_pairs(Xs, erlang:element(3, Heap)),
erlang:element(3, Heap)}}};
e ->
{error, nil}
end.