A Priority Queue implementation based on Pairing Heap.
This module provides a priority queue with support for custom comparison functions, making it suitable for various graph algorithms like Dijkstra's, Prim's, and A*.
Features
- O(1) insertion
- O(1) find-min
- O(log n) amortized delete-min
- Custom comparison functions for flexible ordering
- Functional/persistent data structure
Examples
# Min-priority queue (default)
pq = Yog.PriorityQueue.new()
|> Yog.PriorityQueue.push(5)
|> Yog.PriorityQueue.push(3)
|> Yog.PriorityQueue.push(7)
{:ok, 3, pq} = Yog.PriorityQueue.pop(pq)
# Max-priority queue with custom comparator
pq = Yog.PriorityQueue.new(fn a, b -> a >= b end)
|> Yog.PriorityQueue.push({:node, 5})
|> Yog.PriorityQueue.push({:node, 10})
{:ok, {:node, 10}, _} = Yog.PriorityQueue.pop(pq)
# Priority queue for Dijkstra's algorithm
pq = Yog.PriorityQueue.new(fn {dist1, _}, {dist2, _} -> dist1 <= dist2 end)
|> Yog.PriorityQueue.push({0, :start})
|> Yog.PriorityQueue.push({5, :a})
|> Yog.PriorityQueue.push({3, :b})
Summary
Functions
Checks if the priority queue is empty.
Converts a list to a priority queue.
Creates a new empty priority queue.
Returns the minimum element without removing it.
Removes and returns the minimum element.
Inserts a value into the priority queue.
Returns the number of elements in the queue.
Converts the priority queue to a sorted list.
Types
Functions
Checks if the priority queue is empty.
Examples
iex> Yog.PriorityQueue.empty?(Yog.PriorityQueue.new())
true
iex> Yog.PriorityQueue.empty?(Yog.PriorityQueue.new() |> Yog.PriorityQueue.push(1))
false
Converts a list to a priority queue.
Examples
iex> pq = Yog.PriorityQueue.from_list([3, 1, 4, 1, 5])
iex> {:ok, min, _} = Yog.PriorityQueue.pop(pq)
iex> min
1
@spec from_list([any()], compare_fn()) :: t()
@spec new() :: t()
Creates a new empty priority queue.
By default, uses natural ordering (min-heap for numbers).
Examples
iex> pq = Yog.PriorityQueue.new()
iex> Yog.PriorityQueue.empty?(pq)
true
iex> pq = Yog.PriorityQueue.new(fn a, b -> a >= b end) # max-heap
iex> Yog.PriorityQueue.empty?(pq)
true
@spec new(compare_fn()) :: t()
Returns the minimum element without removing it.
Returns {:ok, value} if the queue is not empty, :error otherwise.
Examples
iex> pq = Yog.PriorityQueue.new() |> Yog.PriorityQueue.push(5) |> Yog.PriorityQueue.push(3)
iex> Yog.PriorityQueue.peek(pq)
{:ok, 3}
iex> Yog.PriorityQueue.peek(Yog.PriorityQueue.new())
:error
Removes and returns the minimum element.
Returns {:ok, value, new_queue} if the queue is not empty, :error otherwise.
Examples
iex> pq = Yog.PriorityQueue.new() |> Yog.PriorityQueue.push(5) |> Yog.PriorityQueue.push(3) |> Yog.PriorityQueue.push(7)
iex> {:ok, min, pq} = Yog.PriorityQueue.pop(pq)
iex> min
3
iex> {:ok, next_min, _} = Yog.PriorityQueue.pop(pq)
iex> next_min
5
Inserts a value into the priority queue.
Examples
iex> pq = Yog.PriorityQueue.new() |> Yog.PriorityQueue.push(5) |> Yog.PriorityQueue.push(3)
iex> Yog.PriorityQueue.peek(pq)
{:ok, 3}
@spec size(t()) :: non_neg_integer()
Returns the number of elements in the queue.
Examples
iex> Yog.PriorityQueue.new() |> Yog.PriorityQueue.push(1) |> Yog.PriorityQueue.push(2) |> Yog.PriorityQueue.size()
2
Converts the priority queue to a sorted list.
Examples
iex> Yog.PriorityQueue.new() |> Yog.PriorityQueue.push(3) |> Yog.PriorityQueue.push(1) |> Yog.PriorityQueue.push(2) |> Yog.PriorityQueue.to_list()
[1, 2, 3]