#Sorted Set

    A mutable set backed by an AVL tree that maintains elements in sorted order.

    #Usage

    #Create

    You can create an empty SortedSet or a SortedSet from other containers.

    ///|
    test {
    let _set1 : @sorted_set.SortedSet[Int] = SortedSet([])
    let _set2 = @sorted_set.singleton(1)
    let _set3 = @sorted_set.from_array([1])
    }

    #Container Operations

    Add an element to the SortedSet in place.

    ///|
    test {
    let set4 = @sorted_set.from_array([1, 2, 3, 4])
    set4.add(5) // ()
    let set6 = @sorted_set.from_array([1, 2, 3, 4, 5])
    @test.assert_eq(set6.to_array(), [1, 2, 3, 4, 5])
    }

    Remove an element from the SortedSet in place.

    ///|
    test {
    let set = @sorted_set.from_array([3, 8, 1])
    set.remove(8) // ()
    let set7 = @sorted_set.from_array([1, 3])
    @test.assert_eq(set7.to_array(), [1, 3])
    }

    Whether an element is in the set.

    ///|
    test {
    let set = @sorted_set.from_array([1, 2, 3, 4])
    @test.assert_eq(set.contains(1), true)
    @test.assert_eq(set.contains(5), false)
    }

    Iterates over the elements in the set.

    ///|
    test {
    let arr = []
    @sorted_set.from_array([1, 2, 3, 4]).each(v => arr.push(v))
    @test.assert_eq(arr, [1, 2, 3, 4])
    }

    Get the size of the set.

    ///|
    test {
    let set = @sorted_set.from_array([1, 2, 3, 4])
    @test.assert_eq(set.length(), 4)
    }

    Whether the set is empty.

    ///|
    test {
    let set : @sorted_set.SortedSet[Int] = SortedSet([])
    @test.assert_eq(set.is_empty(), true)
    }

    #Set Operations

    Union, intersection and difference of two sets. They return a new set that does not overlap with the original sets in memory.

    ///|
    test {
    let set1 = @sorted_set.from_array([3, 4, 5])
    let set2 = @sorted_set.from_array([4, 5, 6])
    let set3 = set1.union(set2)
    @test.assert_eq(set3.to_array(), [3, 4, 5, 6])
    let set4 = set1.intersection(set2)
    @test.assert_eq(set4.to_array(), [4, 5])
    let set5 = set1.difference(set2)
    @test.assert_eq(set5.to_array(), [3])
    }

    Determine the inclusion and separation relationship between two sets.

    ///|
    test {
    let set1 = @sorted_set.from_array([1, 2, 3])
    let set2 = @sorted_set.from_array([7, 2, 9, 4, 5, 6, 3, 8, 1])
    @test.assert_eq(set1.subset(set2), true)
    let set3 = @sorted_set.from_array([4, 5, 6])
    @test.assert_eq(set1.disjoint(set3), true)
    }

    #Symmetric Difference

    Elements in one set but not both:

    ///|
    test {
    let a = @sorted_set.from_array([1, 2, 3])
    let b = @sorted_set.from_array([2, 3, 4])
    @test.assert_eq(a.symmetric_difference(b).to_array(), [1, 4])
    }

    #Range Queries

    range(low, high) returns an iterator over elements in [low, high]:

    ///|
    test {
    let set = @sorted_set.from_array([1, 3, 5, 7, 9, 11])
    let in_range = set.range(3, 9).collect()
    @test.assert_eq(in_range, [3, 5, 7, 9])
    }

    #Indexed Iteration

    eachi iterates with an index (in sorted order):

    ///|
    test {
    let set = @sorted_set.from_array([10, 20, 30])
    let pairs = []
    set.eachi(fn(i, v) { pairs.push((i, v)) })
    @test.assert_eq(pairs, [(0, 10), (1, 20), (2, 30)])
    }

    #Iterators & Conversion

    ///|
    test {
    let set = @sorted_set.from_array([3, 1, 2])
    // iter returns elements in sorted order
    debug_inspect(set.iter().to_array(), content="[1, 2, 3]")
    // to_array
    @test.assert_eq(set.to_array(), [1, 2, 3])
    // from_iter
    let set2 = @sorted_set.from_iter(4, 5, 6)
    @test.assert_eq(set2.to_array(), [4, 5, 6])
    }

    #Copy

    copy() creates a shallow clone:

    ///|
    test {
    let set = @sorted_set.from_array([1, 2, 3])
    let cloned = set.copy()
    cloned.add(4)
    @test.assert_eq(set.to_array(), [1, 2, 3]) // original unchanged
    @test.assert_eq(cloned.to_array(), [1, 2, 3, 4])
    }

    #@debug.Debug

    SortedSet implements @debug.Debug, which allows you to inspect its elements in sorted order.

    ///|
    test {
    let set = @sorted_set.from_array([1, 2, 3])
    debug_inspect(
    set,
    content=(
    #|<SortedSet: [1, 2, 3]>
    ),
    )
    }

    #Performance

    • add: O(log n)
    • remove: O(log n)
    • contains: O(log n)
    • iterate: O(n)
    • space complexity: O(n)

    #Implementation Notes

    The SortedSet is implemented as an AVL tree, a self-balancing binary search tree. After insertions and deletions, the tree automatically rebalances to maintain O(log n) search, insertion, and deletion times.

    Key properties of the AVL tree implementation:
    • Each node stores a height field indicating the height of that subtree
    • The balance factor (height difference between left and right subtrees) is maintained between -1 and 1 for all nodes
    • Rebalancing is done through tree rotations (single and double rotations)

    #Comparison with Other Collections

    • @hashset.HashSet: Provides O(1) average case lookups but doesn't maintain order; use when order doesn't matter
    • @sorted_set.SortedSet: Maintains elements in sorted order; use when you need elements to be sorted

    Choose SortedSet when you need:
    • Elements in sorted order
    • Efficient ordered iteration
    • Logarithmic time operations

    SortedSet

    type SortedSet[V]

    impl Default for SortedSet[K]
    impl Eq for SortedSet[V]
    impl Show for SortedSet[V]

    SortedSet::SortedSet

    #as_free_fn(of, deprecated="Use from_array instead")
    #alias(of, deprecated="Use from_array instead")
    #as_free_fn(from_array)
    #alias(from_array)
    fn[V : Compare + Eq] SortedSet::SortedSet(array : ArrayView[V]) -> SortedSet[V]

    Initialize a set from an array.

    Example

    test {
    let set = @sorted_set.SortedSet([3, 1, 2])
    @test.assert_eq(set.length(), 3)
    }

    SortedSet::add

    fn[V : Compare + Eq] SortedSet::add(self : SortedSet[V], value : V) -> Unit

    Adds a value to the set. If the value already exists, it is replaced.

    SortedSet::contains

    fn[V : Compare + Eq] SortedSet::contains(self : SortedSet[V], value : V) -> Bool

    Returns true if the set contains the given value.

    SortedSet::copy

    #alias(clone, deprecated="`clone` is deprecated, use `copy` instead")
    #alias(deep_clone, deprecated="`deep_clone` is deprecated, use `copy` instead")
    fn[V] SortedSet::copy(self : SortedSet[V]) -> SortedSet[V]

    Returns a shallow copy of the set.

    It is just copying the tree structure, not the values.

    SortedSet::difference

    #alias(diff, deprecated="`diff` is deprecated, use `difference` instead")
    fn[V : Compare + Eq] SortedSet::difference(self : SortedSet[V], src : SortedSet[V]) -> SortedSet[V]

    Returns a new set containing elements in self that are not in src.

    SortedSet::disjoint

    fn[V : Compare + Eq] SortedSet::disjoint(self : SortedSet[V], src : SortedSet[V]) -> Bool

    Returns true if the two sets have no elements in common.

    SortedSet::each

    fn[V] SortedSet::each(self : SortedSet[V], f : (V) -> Unit raise?) -> Unit raise?

    Iterates over all elements in the set in ascending order.

    SortedSet::eachi

    fn[V] SortedSet::eachi(self : SortedSet[V], f : (Int, V) -> Unit raise?) -> Unit raise?

    Iterates over all elements in the set with their index, in ascending order.

    SortedSet::equal

    fn[V : Eq] SortedSet::equal(self : SortedSet[V], other : SortedSet[V]) -> Bool

    SortedSet::from_iter

    #as_free_fn(from_iterator, deprecated="Use SortedSet::from_iter instead.")
    #alias(from_iterator, deprecated="`from_iterator` is deprecated, use `from_iter` instead")
    #as_free_fn
    fn[V : Compare + Eq] SortedSet::from_iter(iter : Iter[V]) -> SortedSet[V]

    Creates a set from an iterator of values.

    SortedSet::intersection

    #alias(intersect, deprecated="`intersect` is deprecated, use `intersection` instead")
    fn[V : Compare + Eq] SortedSet::intersection(self : SortedSet[V], src : SortedSet[V]) -> SortedSet[V]

    Returns a new set containing only elements present in both sets.

    SortedSet::is_empty

    fn[V] SortedSet::is_empty(self : SortedSet[V]) -> Bool

    Returns true if the set contains no elements.

    SortedSet::iter

    #alias(iterator, deprecated="`iterator` is deprecated, use `iter` instead")
    fn[V] SortedSet::iter(self : SortedSet[V]) -> Iter[V]

    Returns an iterator over the elements in ascending order.

    SortedSet::length

    #alias(size, deprecated="`size` is deprecated, use `length` instead")
    fn[V] SortedSet::length(self : SortedSet[V]) -> Int

    Returns the number of elements in the set.

    SortedSet::new

    #as_free_fn(deprecated="Use `SortedSet([])` instead")
    #deprecated("Use `SortedSet([])` instead")
    fn[V] SortedSet::new() -> SortedSet[V]

    Construct an empty set.

    Deprecated: use SortedSet([]) instead.

    SortedSet::range

    fn[V : Compare + Eq] SortedSet::range(self : SortedSet[V], low : V, high : V) -> Iter[V]

    Returns an iterator over elements in the range [low, high] (inclusive).

    SortedSet::remove

    fn[V : Compare + Eq] SortedSet::remove(self : SortedSet[V], value : V) -> Unit

    Removes a value from the set. Does nothing if the value is not present.

    SortedSet::singleton

    #as_free_fn
    fn[V] SortedSet::singleton(value : V) -> SortedSet[V]

    Returns the one-value set containing only value.

    SortedSet::subset

    fn[V : Compare + Eq] SortedSet::subset(self : SortedSet[V], src : SortedSet[V]) -> Bool

    Returns true if every element of self is also in src.

    SortedSet::symmetric_difference

    fn[V : Compare + Eq] SortedSet::symmetric_difference(self : SortedSet[V], other : SortedSet[V]) -> SortedSet[V]

    Returns a new set containing elements that are in either of the two sets, but not in their intersection. In other words, returns a new set containing elements that are in exactly one of the two sets.

    Parameters:

    • self : The first set.
    • other : The second set.

    Returns a new set containing elements that appear in exactly one of the input sets.

    Example:

    test {
    let set1 = @sorted_set.from_array([1, 2, 3, 4])
    let set2 = @sorted_set.from_array([3, 4, 5, 6])
    let diff = set1.symmetric_difference(set2)
    @debug.debug_inspect(
    diff,
    content=(
    #|<SortedSet: [1, 2, 5, 6]>
    ),
    )
    }

    SortedSet::to_array

    fn[V] SortedSet::to_array(self : SortedSet[V]) -> Array[V]

    Converts the set to an array.

    SortedSet::union

    fn[V : Compare + Eq] SortedSet::union(self : SortedSet[V], src : SortedSet[V]) -> SortedSet[V]

    Returns a new set containing all elements from both sets.