std.container.rbtree as Interval Tree?
Eduard Staniloiu
edi33416 at gmail.com
Tue Feb 5 16:24:03 UTC 2019
On Monday, 4 February 2019 at 22:54:01 UTC, James Blachly wrote:
> I tried to implement an interval tree backed by
> std.container.rbtree today and fell flat.
>
> A standard way to make an interval tree is to make an augmented
> tree; I supposed since rbtree was a generic container and
> because I could define opCmp, this should be a cinch. I ran
> into two problems.
>
> First (minor problem), RedBlackTree considers a return value of
> 0 from opCmp equivalent to "equals", which is discordant with
> the guidance given for opCmp.[1] This is a minor pedantic
> point, since you cannot store un-orderable elements in the tree
> anyway.
>
> More importantly, though, I cannot figure out how to implement
> an interval query function on the tree. Typically, the tree
> would have a "key" that is the left position of the interval
> and the augmented part of the tree would be that a second value
> -- a right, or end, position. My Elem == key type is a struct
> encapsulating both of these (start, end; plus some metadata).
>
> For my Interval element type, I overloaded opCmp to take an
> integer, but unfortunately RedBlackTree's upperBound() and
> lowerBound() functions are defined in terms of "Elem" which is
> aliased to the contained element type, rather than a generic
> type.
>
> Q1: Is there a simple or elegant way to do this without
> re-implementing RedBlackTree? I apologize if it is obvious and
> I am missing it. I suppose it may work if I rewrite Interval's
> opCmp to not consider the upper bound, and by creating a dummy
> interval to pass to upperBound and lowerBound, but that seems
> inelegant compared to passing an integer.
>
> Q2: Would replacing "Elem" with a generic type "T" in the
> function signatures for upperBound, lowerBound, and various
> related fns like _firstGreater / _firstGreaterEqual solve this
> problem?
>
> James
>
> [1] https://dlang.org/spec/operatoroverloading.html#eqcmp ("For
> example ... x and y are disjoint sets, then neither x < y nor y
> < x holds, but that does not imply that x == y. Thus, it is
> insufficient to determine equality purely based on opCmp alone.
> ")
I think you are making a slight confusion. Your `Interval` struct
and the `Elem` type that `lowerBound` takes, are the same type.
You can define your RBTree and Interval as follows
```
struct Interval
{
int start;
int end;
}
alias IntervalTree = RedBlackTree!(Interval, (i1, i2) => i1.start
< i2.start);
```
Please see this runable example: https://run.dlang.io/is/4cPTik
The in-order traversal will be the same as the wikipedia example
here: https://en.wikipedia.org/wiki/Interval_tree
Hope this helps.
Cheers,
Edi
More information about the Digitalmars-d-learn
mailing list