@@ -45,11 +45,16 @@ object RedBlackTree {
45
45
def count (tree : Tree [_, _]) = if (tree eq null ) 0 else tree.count
46
46
def update [A , B , B1 >: B ](tree : Tree [A , B ], k : A , v : B1 )(implicit ordering : Ordering [A ]): Tree [A , B1 ] = blacken(upd(tree, k, v))
47
47
def delete [A , B ](tree : Tree [A , B ], k : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = blacken(del(tree, k))
48
- def range [A , B ](tree : Tree [A , B ], low : Option [A ], lowInclusive : Boolean , high : Option [A ], highInclusive : Boolean )(implicit ordering : Ordering [A ]): Tree [A , B ] = {
49
- val after : Option [A => Boolean ] = low.map(key => if (lowInclusive) ordering.lt(_, key) else ordering.lteq(_, key))
50
- val before : Option [A => Boolean ] = high.map(key => if (highInclusive) ordering.lt(key, _) else ordering.lteq(key, _))
51
- blacken(rng(tree, after, before))
48
+ def rangeImpl [A : Ordering , B ](tree : Tree [A , B ], from : Option [A ], until : Option [A ]): Tree [A , B ] = (from, until) match {
49
+ case (Some (from), Some (until)) => this .range(tree, from, until)
50
+ case (Some (from), None ) => this .from(tree, from)
51
+ case (None , Some (until)) => this .until(tree, until)
52
+ case (None , None ) => tree
52
53
}
54
+ def range [A : Ordering , B ](tree : Tree [A , B ], from : A , until : A ): Tree [A , B ] = blacken(doRange(tree, from, until))
55
+ def from [A : Ordering , B ](tree : Tree [A , B ], from : A ): Tree [A , B ] = blacken(doFrom(tree, from))
56
+ def to [A : Ordering , B ](tree : Tree [A , B ], to : A ): Tree [A , B ] = blacken(doTo(tree, to))
57
+ def until [A : Ordering , B ](tree : Tree [A , B ], key : A ): Tree [A , B ] = blacken(doUntil(tree, key))
53
58
54
59
def smallest [A , B ](tree : Tree [A , B ]): Tree [A , B ] = {
55
60
if (tree eq null ) throw new NoSuchElementException (" empty map" )
@@ -202,13 +207,36 @@ object RedBlackTree {
202
207
else append(tree.left, tree.right)
203
208
}
204
209
205
- private [this ] def rng [A , B ](tree : Tree [A , B ], after : Option [ A => Boolean ], before : Option [ A => Boolean ] )(implicit ordering : Ordering [A ]): Tree [A , B ] = {
210
+ private [this ] def doFrom [A , B ](tree : Tree [A , B ], from : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = {
206
211
if (tree eq null ) return null
207
- if (after == None && before == None ) return tree
208
- if (after != None && after.get(tree.key)) return rng(tree.right, after, before);
209
- if (before != None && before.get(tree.key)) return rng(tree.left, after, before);
210
- val newLeft = rng(tree.left, after, None )
211
- val newRight = rng(tree.right, None , before)
212
+ if (ordering.lt(tree.key, from)) return doFrom(tree.right, from)
213
+ val newLeft = doFrom(tree.left, from)
214
+ if (newLeft eq tree.left) tree
215
+ else if (newLeft eq null ) upd(tree.right, tree.key, tree.value)
216
+ else rebalance(tree, newLeft, tree.right)
217
+ }
218
+ private [this ] def doTo [A , B ](tree : Tree [A , B ], to : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = {
219
+ if (tree eq null ) return null
220
+ if (ordering.lt(to, tree.key)) return doTo(tree.left, to)
221
+ val newRight = doTo(tree.right, to)
222
+ if (newRight eq tree.right) tree
223
+ else if (newRight eq null ) upd(tree.left, tree.key, tree.value)
224
+ else rebalance(tree, tree.left, newRight)
225
+ }
226
+ private [this ] def doUntil [A , B ](tree : Tree [A , B ], until : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = {
227
+ if (tree eq null ) return null
228
+ if (ordering.lteq(until, tree.key)) return doUntil(tree.left, until)
229
+ val newRight = doUntil(tree.right, until)
230
+ if (newRight eq tree.right) tree
231
+ else if (newRight eq null ) upd(tree.left, tree.key, tree.value)
232
+ else rebalance(tree, tree.left, newRight)
233
+ }
234
+ private [this ] def doRange [A , B ](tree : Tree [A , B ], from : A , until : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = {
235
+ if (tree eq null ) return null
236
+ if (ordering.lt(tree.key, from)) return doRange(tree.right, from, until);
237
+ if (ordering.lteq(until, tree.key)) return doRange(tree.left, from, until);
238
+ val newLeft = doFrom(tree.left, from)
239
+ val newRight = doUntil(tree.right, until)
212
240
if ((newLeft eq tree.left) && (newRight eq tree.right)) tree
213
241
else if (newLeft eq null ) upd(newRight, tree.key, tree.value);
214
242
else if (newRight eq null ) upd(newLeft, tree.key, tree.value);
0 commit comments