Beispiel #1
0
        //┴ ┐ ─ ┌ ┘ └
        static void Main(string[] args)
        {
            Random rnd = new Random();

            var tree = new LeftLeaningRedBlackTree <int>();

            Node <int>[] items;
            int[]        array = { 10, 20, 30, 40, 50, 25 };
            for (int i = 0; i < array.Length /*50*/; i++)
            {
                //tree.Add(rnd.Next(1, 10));
                tree.Add(array[i]);
                items = tree.PreOrderNode().ToArray();
                Console.Clear();
                Display(items);

                Thread.Sleep(250);
            }

            tree.Remove(50);
            items = tree.PreOrderNode().ToArray();
            Console.Clear();
            Display(items);

            Console.ReadKey();
        }
Beispiel #2
0
        public void DeletionTest()
        {
            // Setup tree and pool
            Random random = new Random(new Guid().GetHashCode());
            int    count  = random.Next(1, 1000);
            var    tuple  = RandomTree(count);
            LeftLeaningRedBlackTree <int> tree = tuple.Tree;
            List <int> pool = new List <int>(tuple.Pool);

            // Remove from tree
            while (pool.Count != 0)
            {
                int index = random.Next(0, pool.Count);
                tree.Remove(pool[index]);
                AssertInvariants(tree);
                pool.RemoveAt(index);
            }

            // Check tree is empty
            Assert.AreEqual(0, tree.Count, "Tree not empty");
        }
        public static ulong Solve_LLRBT(ulong[] arr, ulong m)
        {
            // 10000000 - 48545 ms

            var sumsLeft = new ulong[arr.Length];

            sumsLeft[0] = arr[0] % m;
            for (var i = 1; i < arr.Length; i++)
            {
                sumsLeft[i] = (sumsLeft[i - 1] + arr[i]) % m;
            }

            var sumsSorted = new LeftLeaningRedBlackTree <ulong, int>((x, y) => x.CompareTo(y), (x, y) => x.CompareTo(y));

            foreach (var item in sumsLeft)
            {
                sumsSorted.Add(item, 0);
            }

            var max = arr[0] % m;

            for (var i = 0; i < arr.Length; i++)
            {
                var left = i == 0 ? 0ul : sumsLeft[i - 1];

                var searchme = left == 0 ? (m - 1) : (left - 1);

                foreach (var node in sumsSorted.Search(n => n.Key == searchme ? (bool?)null : n.Key < searchme ? false : true))
                {
                    if (node.Key <= searchme)
                    {
                        max = Math.Max(max, (node.Key + m - left) % m);
                    }
                }

                sumsSorted.Remove(sumsLeft[i], 0);
            }

            return(max);
        }
Beispiel #4
0
        public static ulong Solve(int n, int[][] edges, ulong[] coins)
        {
            if (n == 1)
            {
                return(ulong.MaxValue);
            }

            var adj  = ToDirectedTree(edges, n + 1);
            var head = edges[0][0];

            var sumsBelow = new ulong[n + 1];

            var stack      = new Stack <int>(n + 1);
            var ignoreSums = new bool[n + 1];

            foreach (var node in Traverse_Tree_PostOrder_NonRec(head, v => adj[v]))
            {
                sumsBelow[node] = coins[node - 1] + adj[node].Select(v => sumsBelow[v]).Sum();
            }

            var total = sumsBelow[head];

            var sumsSet = new LeftLeaningRedBlackTree <ulong, int>((x, y) => x.CompareTo(y), (x, y) => x.CompareTo(y));

            for (var i = 1; i <= n; i++)
            {
                sumsSet.Add(sumsBelow[i], i);
            }

            var best = ulong.MaxValue;

            var path = new List <int>(n + 1)
            {
                head
            };
            var notInA = new bool[n + 1];

            notInA[head] = true;

            foreach (var edgeInfo in Traverse_Dfs_WithEvents(head, v => adj[v]))
            {
                var aNode = edgeInfo.Child;

                if (edgeInfo.IsDownNotUp)
                {
                    path.Add(aNode);

                    notInA[edgeInfo.Parent] = true;
                    foreach (var otherChild in adj[edgeInfo.Parent])
                    {
                        if (otherChild != edgeInfo.Child)
                        {
                            foreach (var node in Traverse_Tree_Dfs(otherChild, v => adj[v], stack))
                            {
                                notInA[node] = true;
                            }
                        }
                    }
                }
                else
                {
                    path.RemoveAt(path.Count - 1);

                    notInA[edgeInfo.Parent] = false;
                    foreach (var otherChild in adj[edgeInfo.Parent])
                    {
                        if (otherChild != edgeInfo.Child)
                        {
                            foreach (var node in Traverse_Tree_Dfs(otherChild, v => adj[v], stack))
                            {
                                notInA[node] = false;
                            }
                        }
                    }

                    continue;
                }

                var a = sumsBelow[aNode];

                if (a == total - a)
                {
                    best = Math.Min(best, a);
                }

                foreach (var pathNode in path)
                {
                    if (pathNode != aNode)
                    {
                        var sum = sumsBelow[pathNode];
                        sumsSet.Remove(sum, pathNode);
                        sumsSet.Add(sum - a, pathNode);
                    }
                }

                var searchme = new List <ulong>(3)
                {
                    a
                };
                if (total > 2 * a)
                {
                    searchme.Add(total - 2 * a);
                }
                if (total != a && (total - a) % 2 == 0)
                {
                    searchme.Add((total - a) / 2);
                }

                foreach (var sum in searchme)
                {
                    if (sumsSet.GetValuesForKey(sum).Any(i => notInA[i]))
                    {
                        best = CalcBest(best, a, sum, total - a - sum);
                    }
                }

                foreach (var pathNode in path)
                {
                    if (pathNode != aNode)
                    {
                        var sum = sumsBelow[pathNode];
                        sumsSet.Remove(sum - a, pathNode);
                        sumsSet.Add(sum, pathNode);
                    }
                }
            }

            return(best);
        }
Beispiel #5
0
        public void RemoveKeyMultiple()
        {
            LeftLeaningRedBlackTree <int, int> binaryTree = new LeftLeaningRedBlackTree <int, int>(IntComparison, IntComparison);

            binaryTree.Remove(-1);
        }
Beispiel #6
0
        /// <summary>
        /// Verifies all public methods with a large number of 'random' scenarios.
        /// </summary>
        /// <param name="seed">Seed for Random constructor.</param>
        /// <param name="isMultiDictionary">True if testing a multi-dictionary.</param>
        private static void RandomScenarios(int seed, bool isMultiDictionary)
        {
            // Use fixed sead for reproducability
            Random rand = new Random(seed);

            for (int scenario = 0; scenario < Scenarios; scenario++)
            {
                LeftLeaningRedBlackTree <int, int> binaryTree = isMultiDictionary ?
                                                                new LeftLeaningRedBlackTree <int, int>(IntComparison, IntComparison) :
                                                                new LeftLeaningRedBlackTree <int, int>(IntComparison);

                // Randomize parameters
                int elementBound = rand.Next(1, 100);
                int keyBound     = rand.Next(1, 50);
                int valueBound   = rand.Next(1, 50);

                // Add random elements
                List <KeyValuePair <int, int> > elements = new List <KeyValuePair <int, int> >();
                for (int i = 0; i < elementBound; i++)
                {
                    KeyValuePair <int, int> element = new KeyValuePair <int, int>(rand.Next(keyBound), rand.Next(valueBound));
                    if (!isMultiDictionary)
                    {
                        IEnumerable <KeyValuePair <int, int> > matches = elements.Where(p => p.Key == element.Key).ToList();
                        foreach (KeyValuePair <int, int> match in matches)
                        {
                            elements.Remove(match);
                        }
                    }
                    elements.Add(element);
                    binaryTree.Add(element.Key, element.Value);
                    CheckTree(binaryTree, elements, isMultiDictionary);
                }

                // Try to remove some elements that aren't present
                int removeBound = rand.Next(20);
                for (int i = 0; i < removeBound; i++)
                {
                    int key   = rand.Next(keyBound);
                    int value = rand.Next(valueBound);
                    if (!elements.Where(p => (key == p.Key) && (!isMultiDictionary || (value == p.Value))).Any())
                    {
                        if (isMultiDictionary)
                        {
                            Assert.IsFalse(binaryTree.Remove(key, value));
                        }
                        else
                        {
                            Assert.IsFalse(binaryTree.Remove(key));
                        }
                        CheckTree(binaryTree, elements, isMultiDictionary);
                    }
                }

                // Remove all elements in random order
                while (0 < elements.Count)
                {
                    int index = rand.Next(elements.Count);
                    KeyValuePair <int, int> element = elements[index];
                    elements.RemoveAt(index);
                    if (isMultiDictionary)
                    {
                        Assert.IsTrue(binaryTree.Remove(element.Key, element.Value));
                    }
                    else
                    {
                        Assert.IsTrue(binaryTree.Remove(element.Key));
                    }
                    CheckTree(binaryTree, elements, isMultiDictionary);
                }

                // Final verification
                Assert.IsFalse(binaryTree.Remove(0, 0));
                elements.Clear();
                binaryTree.Clear();
                CheckTree(binaryTree, elements, isMultiDictionary);
            }
        }