I have the following code to find a match for a number in a list of ranges.
public class RangeGroup
{
public uint RangeGroupId { get; set; }
public u
If you populate the list only once you can do a magic trick:
Sort takes O(Nlog(N)) time and is only done once. Binary search takes O(log(N)), which takes at most 17 comparisons for 100.000 items.
Since you indicated that RangeGroup
s are added in order of RangeGroup.Low
and that they do not overlap, you don't need to do any further pre-processing. You can do binary search on the RangeGroups
list to find the range (warning: not fully tested, you'd need to check some edge conditions):
public static RangeGroup Find(uint number) {
int position = RangeGroups.Count / 2;
int stepSize = position / 2;
while (true) {
if (stepSize == 0) {
// Couldn't find it.
return null;
}
if (RangeGroups[position].High < number) {
// Search down.
position -= stepSize;
} else if (RangeGroups[position].Low > number) {
// Search up.
position += stepSize;
} else {
// Found it!
return RangeGroups[position];
}
stepSize /= 2;
}
}
The worst-case run time should be around O(log(N)), where N is the number of RangeGroups.
May be use a sorted list and do a binary search. That way you reduce the number of comparisons to O(logN)
Interval trees. were created exatcly for what you are asking for.
Sort the ranges twice, in two different arrays. Once by least value in the range, once by greatest value in the range. Then do two binary searches, saving the ranges that match either constraint. Finally, do a set intersection of the two sets of possibilities.