Brendan Langfield
Brendan Langfield

Reputation: 585

How do you insert an interval into a disjoint segment tree in Haskell?

I don't think this is standard terminology, but we will define a "disjoint segment tree" as a segment tree (a flavor of binary search tree) whose values are pairwise-separated intervals (a,b) where a <= b, representing blocks of time. I use the word "separated" to disallow adjacent intervals.

I want to write a function to insert an interval into such a tree, preserving the data invariant by merging any overlapping or adjacent intervals. However, I can't figure out what to do in the case where the interval being inserted overlaps with the root interval (see the undefineds below).

Here is a partial solution:

data SegTree = Empty | Node (Int, Int) SegTree SegTree deriving (Eq, Show)

-- | Whether an interval ends strictly before another interval.
isStrictlyBefore :: (Int, Int) -> (Int, Int) -> Bool
(_, b1) `isStrictlyBefore` (a2, _) = b1 < a2

combine :: (Int, Int) -> (Int, Int) -> (Int, Int)
combine (a1,b1) (a2,b2) = (min a1 a2, max b1 b2)

-- | Insert an interval into a segment tree by merging touching intervals.
insertByMerge :: (Int, Int) -> SegTree -> SegTree
insertByMerge x' Empty  = Node x' Empty Empty
insertByMerge x' (Node x l r)
  | x' `isStrictlyBefore` x  = Node x (insertByMerge x' l) r
  | x  `isStrictlyBefore` x' = Node x l (insertByMerge x' r)
  | otherwise = Node undefined undefined undefined
  where
    l' = insertByMerge (combine x x') l
    r' = insertByMerge (combine x x') r

Any pointers?

Upvotes: 0

Views: 88

Answers (0)

Related Questions