1
1
package com .jwetherell .algorithms .data_structures ;
2
2
3
- import java .security .InvalidParameterException ;
4
3
import java .util .ArrayList ;
5
4
import java .util .Collection ;
6
5
import java .util .Collections ;
7
6
import java .util .Comparator ;
8
7
import java .util .HashSet ;
9
- import java .util .Iterator ;
10
8
import java .util .List ;
11
9
import java .util .Set ;
12
10
@@ -23,8 +21,7 @@ public class IntervalTree<O extends Object> {
23
21
24
22
private Interval <O > root = null ;
25
23
26
- private static final Comparator <IntervalData <?>> startComparator = new Comparator <IntervalData <?>>() {
27
-
24
+ private static final Comparator <IntervalData <?>> START_COMPARATOR = new Comparator <IntervalData <?>>() {
28
25
/**
29
26
* {@inheritDoc}
30
27
*/
@@ -39,8 +36,7 @@ public int compare(IntervalData<?> arg0, IntervalData<?> arg1) {
39
36
}
40
37
};
41
38
42
- private static final Comparator <IntervalData <?>> endComparator = new Comparator <IntervalData <?>>() {
43
-
39
+ private static final Comparator <IntervalData <?>> END_COMPARATOR = new Comparator <IntervalData <?>>() {
44
40
/**
45
41
* {@inheritDoc}
46
42
*/
@@ -74,26 +70,29 @@ protected static final <O extends Object> Interval<O> createFromList(List<Interv
74
70
IntervalData <O > middle = intervals .get (0 );
75
71
newInterval .center = ((middle .start + middle .end ) / 2 );
76
72
newInterval .add (middle );
77
- } else {
78
- int half = intervals .size () / 2 ;
79
- IntervalData <O > middle = intervals .get (half );
80
- newInterval .center = ((middle .start + middle .end ) / 2 );
81
- List <IntervalData <O >> leftIntervals = new ArrayList <IntervalData <O >>();
82
- List <IntervalData <O >> rightIntervals = new ArrayList <IntervalData <O >>();
83
- for (IntervalData <O > interval : intervals ) {
84
- if (interval .end < newInterval .center ) {
85
- leftIntervals .add (interval );
86
- } else if (interval .start > newInterval .center ) {
87
- rightIntervals .add (interval );
88
- } else {
89
- newInterval .add (interval );
90
- }
91
- }
92
- if (leftIntervals .size () > 0 )
93
- newInterval .left = createFromList (leftIntervals );
94
- if (rightIntervals .size () > 0 )
95
- newInterval .right = createFromList (rightIntervals );
73
+ return newInterval ;
74
+ }
75
+
76
+ int half = intervals .size () / 2 ;
77
+ IntervalData <O > middle = intervals .get (half );
78
+ newInterval .center = ((middle .start + middle .end ) / 2 );
79
+ List <IntervalData <O >> leftIntervals = new ArrayList <IntervalData <O >>();
80
+ List <IntervalData <O >> rightIntervals = new ArrayList <IntervalData <O >>();
81
+ for (IntervalData <O > interval : intervals ) {
82
+ if (interval .end < newInterval .center ) {
83
+ leftIntervals .add (interval );
84
+ } else if (interval .start > newInterval .center ) {
85
+ rightIntervals .add (interval );
86
+ } else {
87
+ newInterval .add (interval );
88
+ }
96
89
}
90
+
91
+ if (leftIntervals .size () > 0 )
92
+ newInterval .left = createFromList (leftIntervals );
93
+ if (rightIntervals .size () > 0 )
94
+ newInterval .right = createFromList (rightIntervals );
95
+
97
96
return newInterval ;
98
97
}
99
98
@@ -181,7 +180,7 @@ public IntervalData<O> query(long index) {
181
180
IntervalData <O > results = null ;
182
181
if (index < center ) {
183
182
// overlap is sorted by start point
184
- Collections .sort (overlap ,startComparator );
183
+ Collections .sort (overlap ,START_COMPARATOR );
185
184
for (IntervalData <O > data : overlap ) {
186
185
if (data .start > index )
187
186
break ;
@@ -194,7 +193,7 @@ else if (results != null && temp != null)
194
193
}
195
194
} else if (index >= center ) {
196
195
// overlap is reverse sorted by end point
197
- Collections .sort (overlap ,endComparator );
196
+ Collections .sort (overlap ,END_COMPARATOR );
198
197
for (IntervalData <O > data : overlap ) {
199
198
if (data .end < index )
200
199
break ;
@@ -206,6 +205,7 @@ else if (results != null && temp != null)
206
205
results .combined (temp );
207
206
}
208
207
}
208
+
209
209
if (index < center ) {
210
210
if (left != null ) {
211
211
IntervalData <O > temp = left .query (index );
@@ -246,20 +246,23 @@ public IntervalData<O> query(long start, long end) {
246
246
else if (results != null && temp != null )
247
247
results .combined (temp );
248
248
}
249
+
249
250
if (left != null && start < center ) {
250
251
IntervalData <O > temp = left .query (start , end );
251
252
if (temp != null && results == null )
252
253
results = temp ;
253
254
else if (results != null && temp != null )
254
255
results .combined (temp );
255
256
}
257
+
256
258
if (right != null && end >= center ) {
257
259
IntervalData <O > temp = right .query (start , end );
258
260
if (temp != null && results == null )
259
261
results = temp ;
260
262
else if (results != null && temp != null )
261
263
results .combined (temp );
262
264
}
265
+
263
266
return results ;
264
267
}
265
268
@@ -278,7 +281,7 @@ public String toString() {
278
281
/**
279
282
* Data structure representing an interval.
280
283
*/
281
- public static final class IntervalData <O > implements Comparable <IntervalData <O >> {
284
+ public static class IntervalData <O > implements Comparable <IntervalData <O >> {
282
285
283
286
private long start = Long .MIN_VALUE ;
284
287
private long end = Long .MAX_VALUE ;
@@ -318,17 +321,6 @@ public IntervalData(long start, long end, Set<O> set) {
318
321
this .start = start ;
319
322
this .end = end ;
320
323
this .set = set ;
321
-
322
- // Make sure they are unique
323
- Iterator <O > iter = set .iterator ();
324
- while (iter .hasNext ()) {
325
- O obj1 = iter .next ();
326
- O obj2 = null ;
327
- if (iter .hasNext ())
328
- obj2 = iter .next ();
329
- if (obj1 .equals (obj2 ))
330
- throw new InvalidParameterException ("Each interval data in the list must be unique." );
331
- }
332
324
}
333
325
334
326
/**
@@ -389,9 +381,9 @@ public IntervalData<O> combined(IntervalData<O> data) {
389
381
* @return deep copy.
390
382
*/
391
383
public IntervalData <O > copy () {
392
- Set <O > listCopy = new HashSet <O >();
393
- listCopy .addAll (set );
394
- return new IntervalData <O >(start , end , listCopy );
384
+ Set <O > copy = new HashSet <O >();
385
+ copy .addAll (set );
386
+ return new IntervalData <O >(start , end , copy );
395
387
}
396
388
397
389
/**
@@ -404,12 +396,10 @@ public IntervalData<O> copy() {
404
396
* @return Data queried for or NULL if it doesn't match the query.
405
397
*/
406
398
public IntervalData <O > query (long index ) {
407
- if (index < this .start || index > this .end ) {
408
- // Ignore
409
- } else {
410
- return copy ();
411
- }
412
- return null ;
399
+ if (index < this .start || index > this .end )
400
+ return null ;
401
+
402
+ return copy ();
413
403
}
414
404
415
405
/**
@@ -422,12 +412,10 @@ public IntervalData<O> query(long index) {
422
412
* @return Data queried for or NULL if it doesn't match the query.
423
413
*/
424
414
public IntervalData <O > query (long startOfQuery , long endOfQuery ) {
425
- if (endOfQuery < this .start || startOfQuery > this .end ) {
426
- // Ignore
427
- } else {
428
- return copy ();
429
- }
430
- return null ;
415
+ if (endOfQuery < this .start || startOfQuery > this .end )
416
+ return null ;
417
+
418
+ return copy ();
431
419
}
432
420
433
421
/**
@@ -446,6 +434,7 @@ public int hashCode() {
446
434
public boolean equals (Object obj ) {
447
435
if (!(obj instanceof IntervalData ))
448
436
return false ;
437
+
449
438
IntervalData <O > data = (IntervalData <O >) obj ;
450
439
if (this .start == data .start && this .end == data .end ) {
451
440
if (this .set .size () != data .set .size ())
0 commit comments