core/PriorityQueue
A mutable priority queue of elements. Always returns the element with the highest priority first, as determined by a user-provided comparison function.
Typical use cases include:
- Task scheduling (highest-priority task first)
- Event simulation
- Pathfinding algorithms (e.g. Dijkstra, A*)
Example:
import PriorityQueue "mo:core/PriorityQueue";
import Nat "mo:core/Nat";
persistent actor {
let pq = PriorityQueue.empty<Nat>();
PriorityQueue.push(pq, Nat.compare, 5);
PriorityQueue.push(pq, Nat.compare, 10);
PriorityQueue.push(pq, Nat.compare, 3);
assert PriorityQueue.pop(pq, Nat.compare) == ?10;
assert PriorityQueue.pop(pq, Nat.compare) == ?5;
assert PriorityQueue.pop(pq, Nat.compare) == ?3;
assert PriorityQueue.pop(pq, Nat.compare) == null;
}
Internally implemented as a binary heap stored in a core library List.
Performance:
- Runtime:
O(log n)forpushandpop(amortized). - Runtime:
O(1)forpeek,clear,size, andisEmpty. - Space:
O(n), wherenis the number of stored elements.
Implementation note (due to List):
- There is an additive memory overhead of
O(sqrt(n)). - For
pushandpop, the amortized time isO(log n), but the worst case can involve an extraO(sqrt(n))step.
Type PriorityQueue
type PriorityQueue<T> = Types.PriorityQueue<T>
Function empty
func empty<T>() : PriorityQueue<T>
Returns an empty priority queue.
Example:
import PriorityQueue "mo:core/PriorityQueue";
let pq = PriorityQueue.empty<Nat>();
assert PriorityQueue.isEmpty(pq);
Runtime: O(1). Space: O(1).
Function singleton
func singleton<T>(element : T) : PriorityQueue<T>
Returns a priority queue containing a single element.
Example:
import PriorityQueue "mo:core/PriorityQueue";
let pq = PriorityQueue.singleton<Nat>(42);
assert PriorityQueue.peek(pq) == ?42;
Runtime: O(1). Space: O(1).
Function size
func size<T>(self : PriorityQueue<T>) : Nat
Returns the number of elements in the priority queue.
Runtime: O(1).
Function isEmpty
func isEmpty<T>(self : PriorityQueue<T>) : Bool
Returns true iff the priority queue is empty.
Example:
import PriorityQueue "mo:core/PriorityQueue";
import Nat "mo:core/Nat";
let pq = PriorityQueue.empty<Nat>();
assert PriorityQueue.isEmpty(pq);
PriorityQueue.push(pq, Nat.compare, 5);
assert not PriorityQueue.isEmpty(pq);
Runtime: O(1). Space: O(1).
Function clear
func clear<T>(self : PriorityQueue<T>)
Removes all elements from the priority queue.
Example:
import PriorityQueue "mo:core/PriorityQueue";
import Nat "mo:core/Nat";
let pq = PriorityQueue.empty<Nat>();
PriorityQueue.push(pq, Nat.compare, 5);
PriorityQueue.push(pq, Nat.compare, 10);
assert not PriorityQueue.isEmpty(pq);
PriorityQueue.clear(pq);
assert PriorityQueue.isEmpty(pq);
Runtime: O(1). Space: O(1).
Function push
func push<T>(self : PriorityQueue<T>, compare : (implicit : (T, T) -> Order.Order), element : T)
Inserts a new element into the priority queue.
compare – comparison function that defines priority ordering.
Example:
import PriorityQueue "mo:core/PriorityQueue";
import Nat "mo:core/Nat";
let pq = PriorityQueue.empty<Nat>();
PriorityQueue.push(pq, Nat.compare, 5);
PriorityQueue.push(pq, Nat.compare, 10);
assert PriorityQueue.peek(pq) == ?10;
Runtime: O(log n). Space: O(1).
Function peek
func peek<T>(self : PriorityQueue<T>) : ?T
Returns the element with the highest priority, without removing it.
Returns null if the queue is empty.
Example:
import PriorityQueue "mo:core/PriorityQueue";
let pq = PriorityQueue.singleton<Nat>(42);
assert PriorityQueue.peek(pq) == ?42;
Runtime: O(1). Space: O(1).
Function pop
func pop<T>(self : PriorityQueue<T>, compare : (implicit : (T, T) -> Order.Order)) : ?T
Removes and returns the element with the highest priority.
Returns null if the queue is empty.
compare – comparison function that defines priority ordering.
Example:
import PriorityQueue "mo:core/PriorityQueue";
import Nat "mo:core/Nat";
let pq = PriorityQueue.empty<Nat>();
PriorityQueue.push(pq, Nat.compare, 5);
PriorityQueue.push(pq, Nat.compare, 10);
assert PriorityQueue.pop(pq, Nat.compare) == ?10;
Runtime: O(log n). Space: O(1).
Function fromIter
func fromIter<T>(iter : Types.Iter<T>, compare : (implicit : (T, T) -> Order.Order)) : PriorityQueue<T>
Creates a new priority queue from an iterator.
compare – comparison function that defines priority ordering.
Example:
import PriorityQueue "mo:core/PriorityQueue";
import Nat "mo:core/Nat";
let pq = PriorityQueue.fromIter<Nat>([5, 10, 3].values(), Nat.compare);
assert PriorityQueue.size(pq) == 3;
assert PriorityQueue.peek(pq) == ?10;
Runtime: O(n * log(n)).
Space: O(n).
n denotes the number of elements in the iterator.
Function clone
func clone<T>(self : PriorityQueue<T>) : PriorityQueue<T>
Creates a copy of the priority queue.
Example:
import PriorityQueue "mo:core/PriorityQueue";
import Nat "mo:core/Nat";
let original = PriorityQueue.fromIter<Nat>([5, 10, 3].values(), Nat.compare);
let copy = PriorityQueue.clone(original);
assert PriorityQueue.pop(copy, Nat.compare) == ?10;
assert PriorityQueue.size(original) == 3;
Runtime: O(n). Space: O(n).
n denotes the number of elements in the priority queue.
Function values
func values<T>(self : PriorityQueue<T>, compare : (implicit : (T, T) -> Order.Order)) : Types.Iter<T>
Returns an iterator that yields elements in descending priority order
(highest priority first, matching pop semantics).
The original queue is not modified. Internally clones the heap
and pops from the clone on each next() call.
compare – comparison function that defines priority ordering.
Example:
import PriorityQueue "mo:core/PriorityQueue";
import Nat "mo:core/Nat";
import Iter "mo:core/Iter";
let pq = PriorityQueue.fromIter<Nat>([5, 10, 3].values(), Nat.compare);
assert Iter.toArray(PriorityQueue.values(pq, Nat.compare)) == [10, 5, 3];
Runtime: O(n) to create the iterator, O(log n) per next() call.
Space: O(n) for the internal clone.
n denotes the number of elements in the priority queue.