Current section
Files
Jump to
Current section
Files
src/gleamy_structures@heap@leftist_heap.erl
-module(gleamy_structures@heap@leftist_heap).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([new/1, find_min/1, insert/2, delete_min/1]).
-export_type([t/1, heap/1]).
-type t(FJS) :: e | {t, integer(), FJS, t(FJS), t(FJS)}.
-opaque heap(FJT) :: {heap, t(FJT), fun((FJT, FJT) -> gleam@order:order())}.
-spec new(fun((FJU, FJU) -> gleam@order:order())) -> heap(FJU).
new(Compare) ->
{heap, e, Compare}.
-spec find_min(heap(FJZ)) -> {ok, FJZ} | {error, nil}.
find_min(Heap) ->
case erlang:element(2, Heap) of
{t, _, X, _, _} ->
{ok, X};
e ->
{error, nil}
end.
-spec make(FLG, t(FLG), t(FLG)) -> t(FLG).
make(X, A, B) ->
Rank_a = case A of
{t, R, _, _, _} ->
R;
e ->
0
end,
Rank_b = case B of
{t, R@1, _, _, _} ->
R@1;
e ->
0
end,
case Rank_a < Rank_b of
true ->
{t, Rank_a + 1, X, B, A};
_ ->
{t, Rank_b + 1, X, A, B}
end.
-spec merge(t(FKI), t(FKI), fun((FKI, FKI) -> gleam@order:order())) -> t(FKI).
merge(H1, H2, Compare) ->
case {H1, H2} of
{H, e} ->
H;
{e, H@1} ->
H@1;
{{t, _, X, A1, B1}, {t, _, Y, A2, B2}} ->
case Compare(X, Y) of
gt ->
make(Y, A2, merge(H1, B2, Compare));
_ ->
make(X, A1, merge(B1, H2, Compare))
end
end.
-spec insert(heap(FJW), FJW) -> heap(FJW).
insert(Heap, Item) ->
{heap,
merge(
{t, 1, Item, e, e},
erlang:element(2, Heap),
erlang:element(3, Heap)
),
erlang:element(3, Heap)}.
-spec delete_min(heap(FKD)) -> {ok, {FKD, heap(FKD)}} | {error, nil}.
delete_min(Heap) ->
case erlang:element(2, Heap) of
{t, _, X, A, B} ->
{ok,
{X,
{heap,
merge(A, B, erlang:element(3, Heap)),
erlang:element(3, Heap)}}};
e ->
{error, nil}
end.