Current section
Files
Jump to
Current section
Files
src/gleamy@leftist_heap.erl
-module(gleamy@leftist_heap).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-define(FILEPATH, "src/gleamy/leftist_heap.gleam").
-export([new/1, find_min/1, insert/2, delete_min/1, merge/2]).
-export_type([tree/1, heap/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" This module provides an implementation of the leftist heap data structure,\n"
" a type of binary heap with efficient insert, find_min, and delete_min, and merge operations.\n"
).
-type tree(GEO) :: empty | {tree, integer(), GEO, tree(GEO), tree(GEO)}.
-opaque heap(GEP) :: {heap, tree(GEP), fun((GEP, GEP) -> gleam@order:order())}.
-file("src/gleamy/leftist_heap.gleam", 18).
?DOC(" Creates a new empty heap with the provided comparison function.\n").
-spec new(fun((GEQ, GEQ) -> gleam@order:order())) -> heap(GEQ).
new(Compare) ->
{heap, empty, Compare}.
-file("src/gleamy/leftist_heap.gleam", 33).
?DOC(
" Returns the minimum element in the heap, if the heap is not empty.\n"
" Time complexity: O(1)\n"
).
-spec find_min(heap(GEV)) -> {ok, GEV} | {error, nil}.
find_min(Heap) ->
case erlang:element(2, Heap) of
{tree, _, X, _, _} ->
{ok, X};
empty ->
{error, nil}
end.
-file("src/gleamy/leftist_heap.gleam", 72).
-spec make(GGF, tree(GGF), tree(GGF)) -> tree(GGF).
make(X, A, B) ->
Rank_a = case A of
{tree, R, _, _, _} ->
R;
empty ->
0
end,
Rank_b = case B of
{tree, R@1, _, _, _} ->
R@1;
empty ->
0
end,
case Rank_a < Rank_b of
true ->
{tree, Rank_a + 1, X, B, A};
_ ->
{tree, Rank_b + 1, X, A, B}
end.
-file("src/gleamy/leftist_heap.gleam", 60).
-spec merge_trees(tree(GFI), tree(GFI), fun((GFI, GFI) -> gleam@order:order())) -> tree(GFI).
merge_trees(H1, H2, Compare) ->
case {H1, H2} of
{H, empty} ->
H;
{empty, H@1} ->
H@1;
{{tree, _, X, A1, B1}, {tree, _, Y, A2, B2}} ->
case Compare(X, Y) of
gt ->
make(Y, A2, merge_trees(H1, B2, Compare));
_ ->
make(X, A1, merge_trees(B1, H2, Compare))
end
end.
-file("src/gleamy/leftist_heap.gleam", 24).
?DOC(
" Inserts a new item into the heap, preserving the heap property.\n"
" Time complexity: O(log n)\n"
).
-spec insert(heap(GES), GES) -> heap(GES).
insert(Heap, Item) ->
{heap,
merge_trees(
{tree, 1, Item, empty, empty},
erlang:element(2, Heap),
erlang:element(3, Heap)
),
erlang:element(3, Heap)}.
-file("src/gleamy/leftist_heap.gleam", 43).
?DOC(
" Removes and returns the minimum element from the heap, along with the\n"
" new heap after deletion, if the heap is not empty.\n"
" Time complexity: O(log n)\n"
).
-spec delete_min(heap(GEZ)) -> {ok, {GEZ, heap(GEZ)}} | {error, nil}.
delete_min(Heap) ->
case erlang:element(2, Heap) of
{tree, _, X, A, B} ->
{ok,
{X,
{heap,
merge_trees(A, B, erlang:element(3, Heap)),
erlang:element(3, Heap)}}};
empty ->
{error, nil}
end.
-file("src/gleamy/leftist_heap.gleam", 55).
?DOC(
" Merges two heaps into a new heap containing all elements from both heaps,\n"
" preserving the heap property.\n"
" The given heaps must have the same comparison function.\n"
" Time complexity: O(log n)\n"
).
-spec merge(heap(GFE), heap(GFE)) -> heap(GFE).
merge(Heap1, Heap2) ->
Compare = erlang:element(3, Heap1),
{heap,
merge_trees(erlang:element(2, Heap1), erlang:element(2, Heap2), Compare),
Compare}.