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 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 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.
        }