Packages

Data structures in pure Gleam! Including tree, heap, non empty list, map, set, and priority queue.

Current section

Files

Jump to
gleamy_structures src gleamy@pairing_heap.erl
Raw

src/gleamy@pairing_heap.erl

-module(gleamy@pairing_heap).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-define(FILEPATH, "src/gleamy/pairing_heap.gleam").
-export([new/1, find_min/1, insert/2, merge/2, delete_min/1]).
-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 pairing heap data structure,\n"
" a type of self-adjusting heap with efficient insert, find_min, and delete_min, and merge operations.\n"
).
-type tree(HOB) :: empty | {tree, HOB, list(tree(HOB))}.
-opaque heap(HOC) :: {heap, tree(HOC), fun((HOC, HOC) -> gleam@order:order())}.
-file("src/gleamy/pairing_heap.gleam", 18).
?DOC(" Creates a new empty heap with the provided comparison function.\n").
-spec new(fun((HOD, HOD) -> gleam@order:order())) -> heap(HOD).
new(Compare) ->
{heap, empty, Compare}.
-file("src/gleamy/pairing_heap.gleam", 30).
?DOC(
" Returns the minimum element in the heap, if the heap is not empty.\n"
" Time complexity: O(1)\n"
).
-spec find_min(heap(HOI)) -> {ok, HOI} | {error, nil}.
find_min(Heap) ->
case erlang:element(2, Heap) of
{tree, X, _} ->
{ok, X};
empty ->
{error, nil}
end.
-file("src/gleamy/pairing_heap.gleam", 56).
-spec merge_trees(tree(HOV), tree(HOV), fun((HOV, HOV) -> gleam@order:order())) -> tree(HOV).
merge_trees(X, Y, Compare) ->
case {X, Y} of
{X@1, empty} ->
X@1;
{empty, Y@1} ->
Y@1;
{{tree, Xk, Xs}, {tree, Yk, Ys}} ->
case Compare(Xk, Yk) of
gt ->
{tree, Yk, [X | Ys]};
_ ->
{tree, Xk, [Y | Xs]}
end
end.
-file("src/gleamy/pairing_heap.gleam", 24).
?DOC(
" Inserts a new item into the heap, preserving the heap property.\n"
" Time complexity: O(1)\n"
).
-spec insert(heap(HOF), HOF) -> heap(HOF).
insert(Heap, Key) ->
{heap,
merge_trees(
{tree, Key, []},
erlang:element(2, Heap),
erlang:element(3, Heap)
),
erlang:element(3, Heap)}.
-file("src/gleamy/pairing_heap.gleam", 51).
?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(1)\n"
).
-spec merge(heap(HOR), heap(HOR)) -> heap(HOR).
merge(Heap1, Heap2) ->
Compare = erlang:element(3, Heap1),
{heap,
merge_trees(erlang:element(2, Heap1), erlang:element(2, Heap2), Compare),
Compare}.
-file("src/gleamy/pairing_heap.gleam", 68).
-spec merge_pairs(list(tree(HOZ)), fun((HOZ, HOZ) -> gleam@order:order())) -> tree(HOZ).
merge_pairs(L, Compare) ->
case L of
[] ->
empty;
[H] ->
H;
[H1, H2 | Hs] ->
merge_trees(
merge_trees(H1, H2, Compare),
merge_pairs(Hs, Compare),
Compare
)
end.
-file("src/gleamy/pairing_heap.gleam", 40).
?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) amortized\n"
).
-spec delete_min(heap(HOM)) -> {ok, {HOM, heap(HOM)}} | {error, nil}.
delete_min(Heap) ->
case erlang:element(2, Heap) of
{tree, X, Xs} ->
{ok,
{X,
{heap,
merge_pairs(Xs, erlang:element(3, Heap)),
erlang:element(3, Heap)}}};
empty ->
{error, nil}
end.