public void Add(Interval <T> interval) { if (intervals.Count == 0) { intervals.Add(interval); return; } var startPoint = new Interval <T>(interval.Start, interval.Start); var endPoint = new Interval <T>(interval.End, interval.End); TreeSet <Interval <T> > .Node firstNode = intervals.FindEndNode(startPoint); TreeSet <Interval <T> > .Node lastNode = intervals.FindStartNode(endPoint); if (firstNode == null) { firstNode = intervals.FindNodeByIndex(0); } else if (firstNode.Item.Before(interval)) { firstNode = firstNode.Next(); } if (lastNode == null) { lastNode = intervals.FindNodeByIndex(intervals.Count - 1); } else if (lastNode.Item.After(interval)) { lastNode = lastNode.Previous(); } // If no existing intervals overlap, firstOverlappingNode will now be greated than lastOverlappingNode if (firstNode == null || lastNode == null || firstNode.Item.CompareTo(lastNode.Item) > 0) { // Just add the interval intervals.Add(interval); return; } var mergedInterval = interval.Merge(firstNode.Item).Merge(lastNode.Item); // Remove all nodes in the interval var intervalsToRemove = new List <Interval <T> >(); for (var node = firstNode; node != lastNode; node = node.Next()) { intervalsToRemove.Add(node.Item); } foreach (var toRemove in intervalsToRemove) { intervals.Remove(toRemove); } // Just change the last interval instead of deleting it and then inserting a new node // The change won't affects the position in the tree. lastNode.Item.Start = mergedInterval.Start; lastNode.Item.End = mergedInterval.End; }
public void TestTreeSet() { TreeSet <int> ts = new TreeSet <int>(); SortedDictionary <int, object> sd = new SortedDictionary <int, object>(); Random r = new Random(0); List <int> s = new List <int>(); for (int i = 0; i < 1000; i++) { s.Add(i); s.Add(i); } for (int i = 0; i < 2000; i++) { var next = r.Next(2000 - i); int tmp = s[i]; s[i] = s[i + next]; s[i + next] = tmp; } foreach (int x in s) { if (sd.ContainsKey(x)) { bool a = sd.Remove(x); bool b = ts.Remove(x); Assert.AreEqual(a, b); } else { sd.Add(x, null); ts.Add(x); } // Console.WriteLine(ts.ToString()); ts.Validate(); var p = r.Next(1000); Assert.AreEqual(sd.ContainsKey(p), ts.Contains(p)); Assert.AreEqual(sd.Count, ts.Count); int[] v = new int[sd.Count], w = new int[ts.Count]; sd.Keys.CopyTo(v, 0); ts.CopyTo(w, 0); for (int i = 0; i < v.Length; i++) { Assert.AreEqual(v[i], w[i]); } } }
public void TestTreeSetIndexing() { var set = new TreeSet <int>(); for (int i = 0; i < 1000; i++) { set.Add(i); for (int j = 0; j <= i; j++) { Assert.AreEqual(j, set.GetIndex(j)); Assert.AreEqual(j, set.GetItem(j)); } for (int j = i + 1; j < 1000; j++) { Assert.AreEqual(-1, set.GetIndex(j)); Assert.AreEqual(0, set.GetItem(j)); } } for (int i = 0; i < 1000; i++) { set.Remove(i); for (int j = 0; j < 1000; j++) { int expected = j - i - 1; if (expected < 0) { expected = -1; } int actual = set.GetIndex(j); Assert.AreEqual(expected, actual); expected = i + j + 1; if (expected >= 1000) { expected = 0; } actual = set.GetItem(j); Assert.AreEqual(expected, actual); } } }
public void TestPrioQueueMod() { Random r = new Random(0); int[] values = new int[10000]; var notYetInserted = new TreeSet <int>(); var notYetDeleted = new TreeSet <int>(); for (int i = 0; i < 10000; i++) { values[i] = r.Next(1000); notYetInserted.Add(i); } var pq = new PrioQueueMod <int>((x, y) => values[x] - values[y], new ArrayLocator <int>(10000)); while (notYetInserted.Count > 0 || notYetDeleted.Count > 0) { int n = r.Next(Math.Min(100, notYetInserted.Count + 1)); while (n-- > 0) { int id = notYetInserted.GetItem(r.Next(notYetInserted.Count)); notYetInserted.Remove(id); notYetDeleted.Add(id); pq.Insert(id); Assert.IsTrue(pq.IsHeap(0)); } n = r.Next(Math.Min(100, notYetDeleted.Count + 1)); while (n-- > 0) { int id = notYetDeleted.GetItem(r.Next(notYetDeleted.Count)); notYetDeleted.Remove(id); pq.Erase(id); Assert.IsTrue(pq.Empty || pq.IsHeap(0)); } } }