Sign in

    IntervalTree

    Implement IntervalTree using Moonbit

    IntervalTree
    tree
    Data Structure
    Download zip
    Author
    Version
    0.1.3
    License
    Apache-2.0
    Last updated
    last year
    Downloads
    32

    #IntervalTree

    IntervalTree is an efficient interval tree implementation that supports various interval query operations, such as finding overlapping intervals and contained intervals. An interval tree is a special self-balancing binary search tree designed for fast processing of interval queries.

    #๐Ÿš€ Key Features

    โ€ข ๐Ÿ”„ Multiple Construction Methods - Support for empty trees, single interval trees, and creating from arrays โ€ข โž• Add & Query - Easily insert intervals and check for their existence โ€ข โŒ Remove - Remove specific intervals from the tree โ€ข ๐Ÿ” Powerful Queries - Support for finding intervals that overlap with or are contained within specific intervals โ€ข ๐Ÿ“ Interval Types - Support for four interval types: closed [a,b], open (a,b), left-closed right-open [a,b), and left-open right-closed (a,b] โ€ข ๐Ÿง  Generic Support - Can use any type that implements the Compare trait as interval endpoints โ€ข ๐Ÿ”„ Iteration - Traverse all stored intervals and their associated data

    #๐Ÿ“ฅ Installation

    moon add kesmeey/IntervalTree

    #๐Ÿš€ Usage Guide

    #๐Ÿ”จ Creating an Interval Tree

    You can create an interval tree using the new(), singleton(), or from_array() methods.

    // Create an empty interval tree
    let tree : T[Int, String] = @IntervalTree.new()

    // Create with a single interval
    let interval = @IntervalTree.make_interval(10, 20)
    let single_tree = @IntervalTree.singleton(interval, "data")

    // Create from an array of intervals
    let intervals = [
    (@IntervalTree.make_interval(10, 20), "A"),
    (@IntervalTree.make_interval(15, 25), "B"),
    (@IntervalTree.make_interval(5, 15), "C"),
    ]
    let tree_from_array = @IntervalTree.from_array(intervals)

    #โž• Adding Intervals and Data

    Use the insert() method to add intervals and their associated data to the tree.

    let tree : T[Int, String] = @IntervalTree.new() // Create empty tree
    let p1 = tree.insert(@IntervalTree.make_interval(10, 20), "A") // Returns insertion result, true for successful insertion
    println(p1) // true
    println(tree.size()) // 1

    #๐Ÿ” Querying Intervals

    The interval tree supports several powerful query operations. Use the find_overlaps() method to find all intervals that overlap with a given interval, use the find_contained() method to find all intervals completely contained within a given interval, and use the contains() method to check if a specific interval exists in the tree.

    // Create a new tree and add data
    let tree : T[Int, String] = @IntervalTree.new()
    ignore(tree.insert(@IntervalTree.make_interval(10, 20), "A"))
    ignore(tree.insert(@IntervalTree.make_interval(15, 25), "B"))
    ignore(tree.insert(@IntervalTree.make_interval(5, 15), "C"))
    ignore(tree.insert(@IntervalTree.make_interval(30, 40), "D"))

    // Find all intervals that overlap with a given interval
    let query = @IntervalTree.make_interval(12, 18)
    let overlaps = tree.find_overlaps(query)
    assert_eq!(overlaps.length(), 3) // Should find A, B, C

    // Find all intervals completely contained within a given interval
    let container = @IntervalTree.make_interval(5, 30)
    let contained = tree.find_contained(container)
    assert_eq!(contained.length(), 3) // Should find A, B, C

    // Check if a specific interval exists
    if tree.contains(@IntervalTree.make_interval(10, 20)) {
    // Interval exists
    assert_true!(true)
    }

    #โŒ Removing Intervals

    Use the remove() method to remove a specific interval.

    // Create a new tree and add data
    let tree : T[Int, String] = @IntervalTree.new()
    ignore(tree.insert(@IntervalTree.make_interval(10, 20), "A"))
    ignore(tree.insert(@IntervalTree.make_interval(15, 25), "B"))
    ignore(tree.insert(@IntervalTree.make_interval(5, 15), "C"))

    // Remove an existing interval
    let removed = tree.remove(@IntervalTree.make_interval(10, 20))
    assert_eq!(removed, true) // Returns true if the interval exists and was successfully removed
    assert_eq!(tree.size(), 2)

    #๐Ÿงน Clearing the Tree

    Use the clear() method to remove all intervals from the tree.

    // Create a new tree and add data
    let tree : T[Int, String] = @IntervalTree.new()
    ignore(tree.insert(@IntervalTree.make_interval(10, 20), "A"))
    ignore(tree.insert(@IntervalTree.make_interval(15, 25), "B"))

    // Clear the tree
    tree.clear()
    assert_eq!(tree.size(), 0)
    assert_eq!(tree.is_empty(), true)

    #๐Ÿ“ Size and Capacity

    Use the size() and is_empty() methods to check the status of the tree.

    // Create a new tree and add data
    let tree : T[Int, String] = @IntervalTree.new()
    ignore(tree.insert(@IntervalTree.make_interval(10, 20), "A"))
    ignore(tree.insert(@IntervalTree.make_interval(15, 25), "B"))

    // Check size
    let size = tree.size() // Get the number of intervals
    assert_eq!(size, 2)

    // Check if empty after clearing
    tree.clear()
    let empty = tree.is_empty() // Check if the tree is empty
    assert_true!(empty)

    #๐Ÿ”„ Iteration

    Use the each() and eachi() methods to iterate through all intervals in the tree.

    // Create a new tree and add data
    let tree : T[Int, String] = @IntervalTree.new()
    ignore(tree.insert(@IntervalTree.make_interval(10, 20), "A"))
    ignore(tree.insert(@IntervalTree.make_interval(15, 25), "B"))
    ignore(tree.insert(@IntervalTree.make_interval(5, 15), "C"))

    // Collect iteration results
    let values = []

    // Iterate through all intervals and data
    tree.each(fn(interval, value) {
    values.push(value)
    })
    assert_eq!(values.length(), 3)

    // Iterate with indices
    let idx_values = []
    tree.eachi(fn(idx, interval, value) {
    idx_values.push((idx, value))
    })
    assert_eq!(idx_values.length(), 3)

    #๐Ÿ“‹ Converting to Array

    Use the to_array() method to convert all intervals in the tree to an array.

    // Create a new tree and add data
    let tree : T[Int, String] = @IntervalTree.new()
    ignore(tree.insert(@IntervalTree.make_interval(10, 20), "A"))
    ignore(tree.insert(@IntervalTree.make_interval(15, 25), "B"))

    // Convert to array
    let array = tree.to_array()
    // Returns an array of IntervalMatch objects, each containing interval and data
    assert_eq!(array.length(), 2)
    println(array)
    //[{interval: {low: 10, high: 20}, data: "A"}, {interval: {low: 15, high: 25}, data: "B"}]

    #๐ŸŽฏ Index Access

    Use the [] operator to access intervals by index.

    // Create a new tree and add data
    let tree : T[Int, String] = @IntervalTree.new()
    ignore(tree.insert(@IntervalTree.make_interval(10, 20), "A"))
    ignore(tree.insert(@IntervalTree.make_interval(15, 25), "B"))
    ignore(tree.insert(@IntervalTree.make_interval(5, 15), "C"))

    // Access by index
    let match0 = tree[0]
    // Get the first interval's IntervalMatch
    println(match0) // {interval: {low: 5, high: 15}, data: "C"}
    let match1 = tree[1]
    // Get the second interval's IntervalMatch
    println(match1) // {interval: {low: 10, high: 20}, data: "A"}

    #๐Ÿ“ Interval Types

    Support different types of intervals by specifying them through the new_with_options() method.

    // Create a tree with open intervals
    let open_option = IntervalOptions::{
    interval_type: IntervalType::Open,
    allow_duplicates: false,
    }

    let open_tree = @IntervalTree.new_with_options(open_option)
    ignore(open_tree.insert(@IntervalTree.make_interval(10, 20), "A"))
    // Create a tree with closed intervals
    let closed_option = IntervalOptions::{
    interval_type: IntervalType::Closed,
    allow_duplicates: false,
    }

    let closed_tree = @IntervalTree.new_with_options(closed_option)
    ignore(closed_tree.insert(@IntervalTree.make_interval(10, 20), "B"))

    #๐Ÿง  Generic Support

    The interval tree supports any type that implements the Compare trait as interval endpoints, such as Float and String types.

    // Using Float type intervals
    let float_tree : T[Float, String] = @IntervalTree.new()
    let p1 = float_tree.insert(@IntervalTree.make_interval(10.5, 20.5), "A")
    assert_eq!(p1, true) // Successful insertion

    // Using String type intervals
    let string_tree : T[String, Int] = @IntervalTree.new()
    let p2 = string_tree.insert(@IntervalTree.make_interval("a", "z"), 1)
    assert_eq!(p2, true) // Successful insertion

    #๐Ÿ“œ License

    This project is licensed under the Apache-2.0 License. See LICENSE for details.

    #๐Ÿ“ข Contact & Support

    โ€ข Moonbit Community: moonbit-community โ€ข GitHub Issues: Report an Issue

    ๐Ÿ‘‹ If you like this project, give it a โญ! Happy coding! ๐Ÿš€

    Interval

    pub struct Interval[T] {
    low : T
    high : T
    }

    Represents an interval with low and high endpoints
    impl Eq for Interval[T]
    impl Show for Interval[T]

    IntervalMatch

    pub struct IntervalMatch[T, D] {
    interval : Interval[T]
    data : D
    }

    Result of an interval query, containing the interval and associated data
    impl Eq for IntervalMatch[T, D]
    impl Show for IntervalMatch[T, D]

    IntervalOptions

    pub struct IntervalOptions {
    interval_type : IntervalType
    allow_duplicates : Bool
    }

    Options for interval operations

    IntervalType

    pub(all) enum IntervalType {
    Closed
    Open
    LeftClosed
    RightClosed
    }

    Represents the type of interval: closed [a,b], open (a,b), or half-open [a,b) or (a,b]
    impl Eq for IntervalType

    Node

    pub struct Node[V, D] {
    interval : Interval[V]
    data : D
    max_high : V
    left : Node[V, D]?
    right : Node[V, D]?
    height : Int
    }

    Internal node structure for the interval tree
    impl Eq for Node[V, D]
    impl Show for Node[V, D]

    RemoveResult

    pub struct RemoveResult[V, D] {
    node : Node[V, D]?
    removed : Bool
    }

    Removal result
    pub struct T[V, D] {
    root : Node[V, D]?
    size : Int
    options : IntervalOptions
    }

    The main interval tree container
    impl Show for T[V, D]

    T::clear

    fn T::clear[V, D](self : T[V, D]) -> Unit

    Clears all intervals from the tree.

    T::contains

    fn T::contains[V : Compare + Eq, D](self : T[V, D], query : Interval[V]) -> Bool

    Returns true if the tree contains an interval that exactly matches the query.

    T::each

    fn T::each[V, D](self : T[V, D], f : (Interval[V], D) -> Unit) -> Unit

    Iterates over all intervals in the tree.

    T::eachi

    fn T::eachi[V, D](self : T[V, D], f : (Int, Interval[V], D) -> Unit) -> Unit

    Iterates over all intervals in the tree with index.

    T::find_contained

    fn T::find_contained[V : Compare + Eq, D](self : T[V, D], query : Interval[V]) -> Array[IntervalMatch[V, D]]

    Finds all intervals that are completely contained within the query interval.

    T::find_exact

    fn T::find_exact[V : Compare + Eq, D](self : T[V, D], query : Interval[V]) -> Node[V, D]?

    Finds an interval exactly matching the query.

    T::find_overlaps

    fn T::find_overlaps[V : Compare + Eq, D](self : T[V, D], query : Interval[V]) -> Array[IntervalMatch[V, D]]

    Finds all intervals that overlap with the query interval.

    T::insert

    fn T::insert[V : Compare + Eq, D](self : T[V, D], interval : Interval[V], data : D) -> Bool

    Inserts an interval with associated data into the tree. Returns true if the interval was inserted, false if it was rejected or updated.

    T::is_empty

    fn T::is_empty[V, D](self : T[V, D]) -> Bool

    Returns true if the tree is empty.

    T::op_get

    fn T::op_get[V : Compare + Eq, D](self : T[V, D], index : Int) -> IntervalMatch[V, D]

    Implement index access for interval tree

    T::remove

    fn T::remove[V : Compare + Eq, D](self : T[V, D], interval : Interval[V]) -> Bool

    Removes an interval from the tree. Returns true if the interval was found and removed.

    T::size

    fn T::size[V, D](self : T[V, D]) -> Int

    Returns the number of intervals in the tree.

    T::to_array

    fn T::to_array[V, D](self : T[V, D]) -> Array[IntervalMatch[V, D]]

    Converts the tree to an array of IntervalMatch objects.

    balance

    fn balance[V : Compare + Eq, D](node : Node[V, D]) -> Unit

    Balances a node if needed.

    clear

    fn clear[V, D](self : T[V, D]) -> Unit

    Clears all intervals from the tree.

    contains

    fn contains[V : Compare + Eq, D](self : T[V, D], query : Interval[V]) -> Bool

    Returns true if the tree contains an interval that exactly matches the query.

    default_options

    fn default_options() -> IntervalOptions

    Default interval options: closed intervals with no duplicates allowed

    each

    fn each[V, D](self : T[V, D], f : (Interval[V], D) -> Unit) -> Unit

    Iterates over all intervals in the tree.

    eachi

    fn eachi[V, D](self : T[V, D], f : (Int, Interval[V], D) -> Unit) -> Unit

    Iterates over all intervals in the tree with index.

    endpoints_geq

    fn endpoints_geq[V : Compare + Eq](a : V, b : V, interval_type : IntervalType) -> Bool

    Checks if endpoint a is greater than or equal to endpoint b based on interval type.

    endpoints_leq

    fn endpoints_leq[V : Compare + Eq](a : V, b : V, interval_type : IntervalType) -> Bool

    Checks if endpoint a is less than or equal to endpoint b based on interval type.

    endpoints_overlap

    fn endpoints_overlap[V : Compare + Eq](a : V, b : V, interval_type : IntervalType) -> Bool

    Checks if two endpoints overlap based on interval type.

    find_contained

    fn find_contained[V : Compare + Eq, D](self : T[V, D], query : Interval[V]) -> Array[IntervalMatch[V, D]]

    Finds all intervals that are completely contained within the query interval.

    find_contained_helper

    fn find_contained_helper[V : Compare + Eq, D](node : Node[V, D], query : Interval[V], results : Array[IntervalMatch[V, D]], interval_type : IntervalType) -> Unit

    Finds all intervals in the subtree that are completely contained within the query interval.

    find_exact

    fn find_exact[V : Compare + Eq, D](self : T[V, D], query : Interval[V]) -> Node[V, D]?

    Finds an interval exactly matching the query.

    find_exact_helper

    fn find_exact_helper[V : Compare + Eq, D](node : Node[V, D], query : Interval[V]) -> Node[V, D]?

    Finds a node with exactly matching interval.

    find_min

    fn find_min[V, D](node : Node[V, D]) -> Node[V, D]

    Finds the node with the minimum value in the subtree.

    find_overlaps

    fn find_overlaps[V : Compare + Eq, D](self : T[V, D], query : Interval[V]) -> Array[IntervalMatch[V, D]]

    Finds all intervals that overlap with the query interval.

    find_overlaps_helper

    fn find_overlaps_helper[V : Compare + Eq, D](node : Node[V, D], query : Interval[V], results : Array[IntervalMatch[V, D]], interval_type : IntervalType) -> Unit

    Finds all intervals in the subtree that overlap with the query interval.

    from_array

    fn from_array[V : Compare + Eq, D](intervals : Array[(Interval[V], D)], options~ : IntervalOptions = ..) -> T[V, D]

    Creates a new interval tree from an array of intervals and data.

    get_balance_factor

    fn get_balance_factor[V, D](node : Node[V, D]) -> Int

    Gets the balance factor of a node.

    in_order_traverse

    fn in_order_traverse[V, D, R](node : Node[V, D]?, f : (Node[V, D]) -> R, acc : R) -> R

    Helper function for traversing the tree in-order

    insert

    fn insert[V : Compare + Eq, D](self : T[V, D], interval : Interval[V], data : D) -> Bool

    Inserts an interval with associated data into the tree. Returns true if the interval was inserted, false if it was rejected or updated.

    insert_node

    fn insert_node[V : Compare + Eq, D](node : Node[V, D], new_node : Node[V, D]) -> Bool

    Inserts a node into the tree.

    interval_contains

    fn interval_contains[V : Compare + Eq](a : Interval[V], b : Interval[V], interval_type~ : IntervalType = ..) -> Bool

    Checks if interval a contains interval b.

    intervals_overlap

    fn intervals_overlap[V : Compare + Eq](a : Interval[V], b : Interval[V], interval_type~ : IntervalType = ..) -> Bool

    Checks if two intervals overlap.

    is_empty

    fn is_empty[V, D](self : T[V, D]) -> Bool

    Returns true if the tree is empty.

    is_valid_interval

    fn is_valid_interval[V : Compare + Eq](interval : Interval[V]) -> Bool

    Checks if an interval is valid (low <= high).

    left_rotate

    fn left_rotate[V : Compare + Eq, D](x : Node[V, D]) -> Unit

    Left rotation.

    make_interval

    fn make_interval[T : Compare + Eq](low : T, high : T) -> Interval[T]

    Creates an interval with the given endpoints.

    new

    fn new[V : Compare + Eq, D]() -> T[V, D]

    new_with_options

    fn new_with_options[V : Compare + Eq, D](options : IntervalOptions) -> T[V, D]

    Creates a new interval tree with options.

    op_get

    fn op_get[V : Compare + Eq, D](self : T[V, D], index : Int) -> IntervalMatch[V, D]

    Implement index access for interval tree

    remove

    fn remove[V : Compare + Eq, D](self : T[V, D], interval : Interval[V]) -> Bool

    Removes an interval from the tree. Returns true if the interval was found and removed.

    remove_node

    fn remove_node[V : Compare + Eq, D](node : Node[V, D]?, interval : Interval[V]) -> RemoveResult[V, D]

    right_rotate

    fn right_rotate[V : Compare + Eq, D](y : Node[V, D]) -> Unit

    Right rotation.

    singleton

    fn singleton[V : Compare + Eq, D](interval : Interval[V], data : D, options~ : IntervalOptions = ..) -> T[V, D]

    Creates a new interval tree with a single interval.

    size

    fn size[V, D](self : T[V, D]) -> Int

    Returns the number of intervals in the tree.

    to_array

    fn to_array[V, D](self : T[V, D]) -> Array[IntervalMatch[V, D]]

    Converts the tree to an array of IntervalMatch objects.

    update_height_and_max_high

    fn update_height_and_max_high[V : Compare + Eq, D](node : Node[V, D]) -> Unit

    Updates height and max_high values of a node.

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    ยฉ 2026 mooncakes.io