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 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 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 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 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);
                }
            }
        }