public void CanConstructKeyCollections() { RedBlackTree <int, string> redBlackTree = new RedBlackTree <int, string> { { 1, "1" }, { 2, "2" }, { 3, "3" }, { 4, "4" }, { 5, "5" }, }; ICollection <int> keys = redBlackTree.Keys; Assert.That(keys, Is.Not.Null); Assert.That(keys.Count, Is.EqualTo(5)); WeightedRedBlackTree <int, string> redBlackTree2 = new WeightedRedBlackTree <int, string> { { 1, "1" }, { 2, "2" }, { 3, "3" }, { 4, "4" }, { 5, "5" }, }; keys = redBlackTree2.Keys; Assert.That(keys, Is.Not.Null); Assert.That(keys.Count, Is.EqualTo(5)); }
public void CanReadThroughAsDictionaryWeighted() { WeightedRedBlackTree <int, string> tree = new WeightedRedBlackTree <int, string> { { 1, "1" }, { 2, "2" }, { 3, "3" }, { 4, "4" }, { 5, "5" }, }; IDictionary <int, string> dictionary = tree.AsDictionary(); Assert.That(dictionary[2], Is.EqualTo("2")); Assert.That(dictionary.Count, Is.EqualTo(5)); Assert.That(dictionary.Contains(new KeyValuePair <int, string>(2, "2")), Is.True); Assert.That(dictionary.Contains(new KeyValuePair <int, string>(2, "6")), Is.False); Assert.That(dictionary.Contains(new KeyValuePair <int, string>(6, "2")), Is.False); Assert.That(dictionary.Contains(new KeyValuePair <int, string>(6, "6")), Is.False); Assert.That(dictionary.Contains(new KeyValuePair <int, string>(2, null)), Is.False); Assert.That(dictionary.ContainsKey(2), Is.True); Assert.That(dictionary.ContainsKey(6), Is.False); Assert.That(dictionary.IsReadOnly, Is.False); Assert.That(dictionary.TryGetValue(2, out string value), Is.True); Assert.That(value, Is.EqualTo("2")); Assert.That(dictionary.TryGetValue(6, out value), Is.False); }
public void PreviousShouldBeAbleToWalkTheTreeBackward() { int seed = 12345; int RandomNext() { seed = (seed * 69069) + 12345; return((seed >> 16) & 0x7FFF); } WeightedRedBlackTree <int, int> tree = new WeightedRedBlackTree <int, int>(); List <int> keys = new List <int>(); for (int i = 0; i < 500; i++) { int key = RandomNext(); keys.Add(key); tree.Add(key, i); if (IsFibonacci(i)) { List <WeightedRedBlackTreeNode <int, int> > actualNodes = new List <WeightedRedBlackTreeNode <int, int> >(); for (WeightedRedBlackTreeNode <int, int> node = tree.MaximumNode; node != null; node = node.Previous()) { actualNodes.Add(node); } int[] actualKeys = actualNodes.Select(n => n.Key).ToArray(); int[] expectedKeys = keys.OrderByDescending(k => k).ToArray(); CollectionAssert.AreEqual(actualKeys, expectedKeys); } } }
public void TreeShouldBeValidAfterManyRandomDeletions() { int seed = 12345; int RandomNext() { seed = (seed * 69069) + 12345; return((seed >> 16) & 0x7FFF); } WeightedRedBlackTree <int, int> tree = new WeightedRedBlackTree <int, int>(); List <Tuple <int, int> > insertions = new List <Tuple <int, int> >(); for (int i = 0; i < 500; i++) { int key = RandomNext(); insertions.Add(new Tuple <int, int>(key, i)); Assert.That(tree.Count, Is.EqualTo(i)); Assert.That(tree.TryGetValue(key, out int oldValue), Is.False); Assert.That(tree.ContainsKey(key), Is.False); tree.Add(key, i); if (IsFibonacci(i)) { tree.Validate(); } Assert.That(tree.ContainsKey(key), Is.True); Assert.That(tree[key], Is.EqualTo(i)); Assert.That(tree.TryGetValue(key, out int newValue), Is.True); Assert.That(newValue, Is.EqualTo(i)); Assert.That(tree.Count, Is.EqualTo(i + 1)); } for (int i = 0; i < 500; i++) { int key = insertions[i].Item1; int value = insertions[i].Item2; Assert.That(tree.ContainsKey(key), Is.True); Assert.That(tree[key], Is.EqualTo(value)); Assert.That(tree.TryGetValue(key, out int newValue), Is.True); Assert.That(newValue, Is.EqualTo(value)); Assert.That(tree.Count, Is.EqualTo(500 - i)); Assert.That(tree.Remove(key), Is.True); if (IsFibonacci(i)) { tree.Validate(); } Assert.That(tree.ContainsKey(key), Is.False); Assert.That(tree.TryGetValue(key, out int oldValue), Is.False); Assert.That(tree.Count, Is.EqualTo(500 - i - 1)); } }
public void CanUseTheIndexerToReplaceOrInsertValues() { WeightedRedBlackTree <int, int> tree = new WeightedRedBlackTree <int, int> { { 1, 10 }, { 3, 20 }, { 5, 30 }, { 7, 40 }, { 9, 50 }, }; tree[5] = 35; tree[7] = 45; tree[9] = 55; tree[10] = 60; tree[int.MinValue] = -1; tree[0] = 12345; tree[int.MaxValue] = 999; CollectionAssert.AreEqual(tree.KeyValuePairs, new[] { new KeyValuePair <int, int>(int.MinValue, -1), new KeyValuePair <int, int>(0, 12345), new KeyValuePair <int, int>(1, 10), new KeyValuePair <int, int>(3, 20), new KeyValuePair <int, int>(5, 35), new KeyValuePair <int, int>(7, 45), new KeyValuePair <int, int>(9, 55), new KeyValuePair <int, int>(10, 60), new KeyValuePair <int, int>(int.MaxValue, 999), }); }
public void CanConstructValueCollections() { RedBlackTree <int, string> redBlackTree = new RedBlackTree <int, string> { { 1, "1" }, { 2, "2" }, { 3, "3" }, { 4, "4" }, { 5, "5" }, }; ICollection <string> values = redBlackTree.Values; Assert.That(values, Is.Not.Null); Assert.That(values.Count, Is.EqualTo(5)); WeightedRedBlackTree <int, string> redBlackTree2 = new WeightedRedBlackTree <int, string> { { 1, "1" }, { 2, "2" }, { 3, "3" }, { 4, "4" }, { 5, "5" }, }; values = redBlackTree2.Values; Assert.That(values, Is.Not.Null); Assert.That(values.Count, Is.EqualTo(5)); }
public void CanConstructPairCollections() { RedBlackTree <int, string> redBlackTree = new RedBlackTree <int, string> { { 1, "1" }, { 2, "2" }, { 3, "3" }, { 4, "4" }, { 5, "5" }, }; ICollection <KeyValuePair <int, string> > pairs = redBlackTree.KeyValuePairs; Assert.That(pairs, Is.Not.Null); Assert.That(pairs.Count, Is.EqualTo(5)); WeightedRedBlackTree <int, string> redBlackTree2 = new WeightedRedBlackTree <int, string> { { 1, "1" }, { 2, "2" }, { 3, "3" }, { 4, "4" }, { 5, "5" }, }; pairs = redBlackTree2.KeyValuePairs; Assert.That(pairs, Is.Not.Null); Assert.That(pairs.Count, Is.EqualTo(5)); }
public void NewTreeShouldBeEmpty() { WeightedRedBlackTree <int, int> tree = new WeightedRedBlackTree <int, int>(); Assert.That(tree.Root, Is.Null); Assert.That(tree.Count, Is.Zero); tree.Validate(); }
public void CanMutateThroughAsDictionaryWeighted() { WeightedRedBlackTree <int, string> tree = new WeightedRedBlackTree <int, string> { { 1, "1" }, { 2, "2" }, { 3, "3" }, { 4, "4" }, { 5, "5" }, }; IDictionary <int, string> dictionary = tree.AsDictionary(); dictionary[3] = "foo"; Assert.That(tree.Find(3).Value, Is.EqualTo("foo")); dictionary.Add(6, "6"); Assert.That(tree.Find(6).Value, Is.EqualTo("6")); dictionary.Add(new KeyValuePair <int, string>(7, "7")); Assert.That(tree.Find(7).Value, Is.EqualTo("7")); Assert.That(dictionary.Remove(3), Is.True); Assert.That(tree.Find(3), Is.Null); Assert.That(dictionary.Remove(new KeyValuePair <int, string>(8, "8")), Is.False); dictionary.Add(8, null); Assert.That(dictionary.Remove(new KeyValuePair <int, string>(2, null)), Is.False); Assert.That(dictionary.Remove(new KeyValuePair <int, string>(2, "2")), Is.True); Assert.That(tree.Find(2), Is.Null); Assert.That(dictionary.Remove(new KeyValuePair <int, string>(8, "8")), Is.False); Assert.That(dictionary.Remove(new KeyValuePair <int, string>(8, null)), Is.True); Assert.That(tree.Find(8), Is.Null); CollectionAssert.AreEqual(tree.KeyValuePairs, new[] { new KeyValuePair <int, string>(1, "1"), new KeyValuePair <int, string>(4, "4"), new KeyValuePair <int, string>(5, "5"), new KeyValuePair <int, string>(6, "6"), new KeyValuePair <int, string>(7, "7"), }); dictionary.Clear(); Assert.That(tree.Root, Is.Null); Assert.That(tree.Count, Is.Zero); }
public void ForeachShouldWalkTheTreeForward() { int seed = 12345; int RandomNext() { seed = (seed * 69069) + 12345; return((seed >> 16) & 0x7FFF); } WeightedRedBlackTree <int, int> tree = new WeightedRedBlackTree <int, int>(); { List <WeightedRedBlackTreeNode <int, int> > actualNodes = new List <WeightedRedBlackTreeNode <int, int> >(); foreach (WeightedRedBlackTreeNode <int, int> node in tree) { actualNodes.Add(node); } int[] actualKeys = actualNodes.Select(n => n.Key).ToArray(); CollectionAssert.AreEqual(actualKeys, new int[0]); } List <int> keys = new List <int>(); for (int i = 0; i < 500; i++) { int key = RandomNext(); keys.Add(key); tree.Add(key, i); if (IsFibonacci(i)) { List <WeightedRedBlackTreeNode <int, int> > actualNodes = new List <WeightedRedBlackTreeNode <int, int> >(); foreach (WeightedRedBlackTreeNode <int, int> node in tree) { actualNodes.Add(node); } int[] actualKeys = actualNodes.Select(n => n.Key).ToArray(); int[] expectedKeys = keys.OrderBy(k => k).ToArray(); CollectionAssert.AreEqual(actualKeys, expectedKeys); } } }
public void CanConstructAReadOnlyWeightedRedBlackTreeWrapper() { WeightedRedBlackTree <int, string> tree = new WeightedRedBlackTree <int, string> { { 1, "1" }, { 2, "2" }, { 3, "3" }, { 4, "4" }, { 5, "5" }, }; ReadOnlyWeightedRedBlackTree <int, string> wrapper = new ReadOnlyWeightedRedBlackTree <int, string>(tree); Assert.That(wrapper, Is.Not.Null); Assert.That(wrapper.Compare, Is.EqualTo(tree.Compare)); Assert.That(wrapper.Root, Is.EqualTo(tree.Root)); Assert.That(wrapper.Count, Is.EqualTo(5)); Assert.That(wrapper.MinimumNode.Key, Is.EqualTo(1)); Assert.That(wrapper.MaximumNode.Key, Is.EqualTo(5)); }
public void CanReadAsCollectionThroughAsDictionaryWeighted() { WeightedRedBlackTree <int, string> tree = new WeightedRedBlackTree <int, string> { { 1, "1" }, { 2, "2" }, { 3, "3" }, { 4, "4" }, { 5, "5" }, }; IDictionary <int, string> dictionary = tree.AsDictionary(); KeyValuePair <int, string>[] array = new KeyValuePair <int, string> [5]; dictionary.CopyTo(array, 0); CollectionAssert.AreEquivalent(array, new[] { new KeyValuePair <int, string>(1, "1"), new KeyValuePair <int, string>(2, "2"), new KeyValuePair <int, string>(3, "3"), new KeyValuePair <int, string>(4, "4"), new KeyValuePair <int, string>(5, "5"), }); CollectionAssert.AreEquivalent(dictionary.Keys, new[] { 1, 2, 3, 4, 5 }); CollectionAssert.AreEquivalent(dictionary.Values, new[] { "1", "2", "3", "4", "5" }); int index = 0; array = new KeyValuePair <int, string> [5]; foreach (KeyValuePair <int, string> pair in dictionary) { array[index++] = pair; } CollectionAssert.AreEquivalent(array, new[] { new KeyValuePair <int, string>(1, "1"), new KeyValuePair <int, string>(2, "2"), new KeyValuePair <int, string>(3, "3"), new KeyValuePair <int, string>(4, "4"), new KeyValuePair <int, string>(5, "5"), }); }
public void ShouldBeAbleToFindMinimaAndMaxima() { int seed = 12345; int RandomNext() { seed = (seed * 69069) + 12345; return((seed >> 16) & 0x7FFF); } WeightedRedBlackTree <int, int> tree = new WeightedRedBlackTree <int, int>(); Assert.That(tree.MinimumKey, Is.EqualTo(default(int))); Assert.That(tree.MaximumKey, Is.EqualTo(default(int))); Assert.That(tree.MinimumNode, Is.Null); Assert.That(tree.MaximumNode, Is.Null); List <int> keys = new List <int>(); for (int i = 0; i < 500; i++) { int key = RandomNext(); keys.Add(key); tree.Add(key, i); int expectedMinimum = keys.Min(); int actualMinimum = tree.MinimumKey; Assert.That(expectedMinimum, Is.EqualTo(actualMinimum)); WeightedRedBlackTreeNode <int, int> actualMinimumNode = tree.MinimumNode; Assert.That(expectedMinimum, Is.EqualTo(actualMinimumNode.Key)); int expectedMaximum = keys.Max(); int actualMaximum = tree.MaximumKey; Assert.That(expectedMaximum, Is.EqualTo(actualMaximum)); WeightedRedBlackTreeNode <int, int> actualMaximumNode = tree.MaximumNode; Assert.That(expectedMaximum, Is.EqualTo(actualMaximumNode.Key)); } }
public void CanUseAnExplicitComparisonFunction() { int CompareFoos(Foo a, Foo b) { return(a.Value.CompareTo(b.Value)); } WeightedRedBlackTree <Foo, int> tree = new WeightedRedBlackTree <Foo, int>(CompareFoos) { { new Foo(1), 10 }, { new Foo(3), 20 }, { new Foo(5), 30 }, { new Foo(7), 40 }, { new Foo(9), 50 }, }; tree[new Foo(5)] = 35; tree[new Foo(7)] = 45; tree[new Foo(9)] = 55; tree[new Foo(10)] = 60; tree[new Foo(int.MinValue)] = -1; tree[new Foo(0)] = 12345; tree[new Foo(int.MaxValue)] = 999; CollectionAssert.AreEqual(tree.KeyValuePairs, new[] { new KeyValuePair <Foo, int>(new Foo(int.MinValue), -1), new KeyValuePair <Foo, int>(new Foo(0), 12345), new KeyValuePair <Foo, int>(new Foo(1), 10), new KeyValuePair <Foo, int>(new Foo(3), 20), new KeyValuePair <Foo, int>(new Foo(5), 35), new KeyValuePair <Foo, int>(new Foo(7), 45), new KeyValuePair <Foo, int>(new Foo(9), 55), new KeyValuePair <Foo, int>(new Foo(10), 60), new KeyValuePair <Foo, int>(new Foo(int.MaxValue), 999), }); }
public void ToDictionaryShouldGenerateAnEquivalentDictionary() { int seed = 12345; int RandomNext() { seed = (seed * 69069) + 12345; return((seed >> 16) & 0x7FFF); } WeightedRedBlackTree <int, int> tree = new WeightedRedBlackTree <int, int>(); { Dictionary <int, int> dictionary = tree.ToDictionary(); Assert.That(dictionary.Count, Is.Zero); } List <int> keys = new List <int>(); for (int i = 0; i < 500; i++) { int key = RandomNext(); keys.Add(key); tree.Add(key, i); if (IsFibonacci(i)) { Dictionary <int, int> dictionary = tree.ToDictionary(); List <KeyValuePair <int, int> > expectedPairs = tree.Select(n => n.ToKeyValuePair()).ToList(); List <KeyValuePair <int, int> > actualPairs = dictionary.OrderBy(p => p.Key).ToList(); CollectionAssert.AreEqual(actualPairs, expectedPairs); } } }
public void CanCopyToSpecialCaseTrees() { { WeightedRedBlackTree <int, int> tree = new WeightedRedBlackTree <int, int>(); Assert.That(tree.Root, Is.Null); // CopyTo should safely bail if the root is null. WeightedRedBlackTreeNode <int, int>[] actualNodes = new WeightedRedBlackTreeNode <int, int> [0]; tree.CopyTo(actualNodes, 0); int[] actualKeys = actualNodes.Select(n => n.Key).ToArray(); CollectionAssert.AreEqual(actualKeys, new int[0]); } { WeightedRedBlackTree <int, int> tree = new WeightedRedBlackTree <int, int> { { 1, 10 }, }; // The above is a valid red-black tree with only one node. Assert.That(tree.Root.Key, Is.EqualTo(1)); // CopyTo performs an inorder walk using Next(), starting at // Root's minimum subnode. List <WeightedRedBlackTreeNode <int, int> > actualNodes = tree.ToList(); int[] actualKeys = actualNodes.Select(n => n.Key).ToArray(); CollectionAssert.AreEqual(actualKeys, new[] { 1 }); } { WeightedRedBlackTree <int, int> tree = new WeightedRedBlackTree <int, int> { { 2, 20 }, { 1, 10 }, }; // The above is a valid red-black tree in which the root is 2 // and it has a left child of 1. Let's check that to be sure... Assert.That(tree.Root.Key, Is.EqualTo(2)); Assert.That(tree.Root.Left.Key, Is.EqualTo(1)); // CopyTo performs an inorder walk using Next(), starting at // Root's minimum subnode. In this case, we ensure that // Root is non-null and has a minimum subnode to start at. List <WeightedRedBlackTreeNode <int, int> > actualNodes = tree.ToList(); int[] actualKeys = actualNodes.Select(n => n.Key).ToArray(); CollectionAssert.AreEqual(actualKeys, new[] { 1, 2 }); } { WeightedRedBlackTree <int, int> tree = new WeightedRedBlackTree <int, int> { { 1, 10 }, { 2, 20 }, }; // The above is a valid red-black tree in which the root is 1 // and it has a right child of 2. Let's check that to be sure... Assert.That(tree.Root.Key, Is.EqualTo(1)); Assert.That(tree.Root.Right.Key, Is.EqualTo(2)); // CopyTo performs an inorder walk using Next(), starting at // Root's minimum subnode. In this case, we ensure that // Root is non-null but has no minimum subnode to start at. List <WeightedRedBlackTreeNode <int, int> > actualNodes = tree.ToList(); int[] actualKeys = actualNodes.Select(n => n.Key).ToArray(); CollectionAssert.AreEqual(actualKeys, new[] { 1, 2 }); } }
public void CannotRemoveKeysThatDontExist() { WeightedRedBlackTree <int, int> tree = new WeightedRedBlackTree <int, int> { { 1, 10 }, { 3, 20 }, { 5, 30 }, { 7, 40 }, { 9, 50 }, }; Assert.That(tree.Remove(4), Is.False); CollectionAssert.AreEqual(tree.KeyValuePairs, new[] { new KeyValuePair <int, int>(1, 10), new KeyValuePair <int, int>(3, 20), new KeyValuePair <int, int>(5, 30), new KeyValuePair <int, int>(7, 40), new KeyValuePair <int, int>(9, 50), }); Assert.That(tree.Remove(3), Is.True); CollectionAssert.AreEqual(tree.KeyValuePairs, new[] { new KeyValuePair <int, int>(1, 10), new KeyValuePair <int, int>(5, 30), new KeyValuePair <int, int>(7, 40), new KeyValuePair <int, int>(9, 50), }); Assert.That(tree.Remove(1), Is.True); CollectionAssert.AreEqual(tree.KeyValuePairs, new[] { new KeyValuePair <int, int>(5, 30), new KeyValuePair <int, int>(7, 40), new KeyValuePair <int, int>(9, 50), }); Assert.That(tree.Remove(7), Is.True); CollectionAssert.AreEqual(tree.KeyValuePairs, new[] { new KeyValuePair <int, int>(5, 30), new KeyValuePair <int, int>(9, 50), }); Assert.That(tree.Remove(9), Is.True); CollectionAssert.AreEqual(tree.KeyValuePairs, new[] { new KeyValuePair <int, int>(5, 30), }); WeightedRedBlackTreeNode <int, int> fiveNode = tree.Find(5); Assert.That(tree.Remove(5), Is.True); tree.DeleteNode(null); // Make this is always a no-op. CollectionAssert.AreEqual(tree.KeyValuePairs, new KeyValuePair <int, int> [0]); Assert.That(tree.Remove(3), Is.False); Assert.That(tree.Count, Is.Zero); Assert.That(tree.Root, Is.Null); tree.DeleteNode(fiveNode); // Make sure nothing bad happens with an empty tree. }