/// <summary> /// Returns all intervals that overlaps with this interval. /// </summary> private List <OneDimentionalInterval <T> > getOverlaps(RedBlackTreeNode <OneDimentionalInterval <T> > current, OneDimentionalInterval <T> searchInterval, List <OneDimentionalInterval <T> > result = null) { if (result == null) { result = new List <OneDimentionalInterval <T> >(); } if (current == null) { return(result); } if (doOverlap(current.Value, searchInterval)) { result.Add(current.Value); } //if left max is greater than search start //then the search interval can occur in left sub tree if (current.Left != null && current.Left.Value.MaxEnd.CompareTo(searchInterval.Start) >= 0) { getOverlaps(current.Left, searchInterval, result); } //otherwise look in right subtree getOverlaps(current.Right, searchInterval, result); return(result); }
/// <summary> /// Does this interval a overlap with b. /// </summary> private bool doOverlap(OneDimentionalInterval <T> a, OneDimentionalInterval <T> b) { //lazy reset a.MatchingEndIndex = -1; b.MatchingEndIndex = -1; for (var i = 0; i < a.End.Count; i++) { for (var j = 0; j < b.End.Count; j++) { //a.Start less than b.End and a.End greater than b.Start if (a.Start.CompareTo(b.End[j]) > 0 || a.End[i].CompareTo(b.Start) < 0) { continue; } a.MatchingEndIndex = i; b.MatchingEndIndex = j; return(true); } } return(false); }
/// <summary> /// Swap intervals so that start always appear before end. /// </summary> private void sortInterval(OneDimentionalInterval <T> value) { if (value.Start.CompareTo(value.End[0]) <= 0) { return; } var tmp = value.End[0]; value.End[0] = value.Start; value.Start = tmp; }
/// <summary> /// Insert a new Interval. /// </summary> internal void Insert(OneDimentionalInterval <T> newInterval) { sortInterval(newInterval); var existing = redBlackTree.FindNode(newInterval); if (existing != null) { existing.Value.End.Add(newInterval.End[0]); } else { existing = redBlackTree.InsertAndReturnNode(newInterval).Item1; } updateMax(existing); Count++; }
/// <summary> /// Delete this interval /// </summary> internal void Delete(OneDimentionalInterval <T> interval) { sortInterval(interval); var existing = redBlackTree.FindNode(interval); if (existing != null && existing.Value.End.Count > 1) { existing.Value.End.RemoveAt(existing.Value.End.Count - 1); updateMax(existing); } else if (existing != null) { redBlackTree.Delete(interval); updateMax(existing.Parent); } else { throw new Exception("Interval not found in this interval tree."); } Count--; }
/// <summary> /// Returns an interval that overlaps with this interval /// </summary> private OneDimentionalInterval <T> getOverlap(RedBlackTreeNode <OneDimentionalInterval <T> > current, OneDimentionalInterval <T> searchInterval) { while (true) { if (current == null) { return(null); } if (doOverlap(current.Value, searchInterval)) { return(current.Value); } //if left max is greater than search start //then the search interval can occur in left sub tree if (current.Left != null && current.Left.Value.MaxEnd.CompareTo(searchInterval.Start) >= 0) { current = current.Left; continue; } //otherwise look in right subtree current = current.Right; } }
/// <summary> /// Does any interval overlaps with this search interval. /// </summary> internal bool DoOverlap(OneDimentionalInterval <T> searchInterval) { sortInterval(searchInterval); return(getOverlap(redBlackTree.Root, searchInterval) != null); }
/// <summary> /// Returns an interval in this tree that overlaps with this search interval. /// </summary> internal List <OneDimentionalInterval <T> > GetOverlaps(OneDimentionalInterval <T> searchInterval) { sortInterval(searchInterval); return(getOverlaps(redBlackTree.Root, searchInterval)); }
public int CompareTo(OneDimentionalInterval <T> other) { return(comparer.Compare(Start, other.Start)); }