Ejemplo n.º 1
0
        public void GetHeight_ForSeveralNodesInSampleTree_ExpectsCorrectHeights()
        {
            var A = new AVLTreeNode <int, string>(50, "A");
            var B = new AVLTreeNode <int, string>(20, "B");
            var C = new AVLTreeNode <int, string>(10, "C");
            var D = new AVLTreeNode <int, string>(40, "D");
            var E = new AVLTreeNode <int, string>(30, "E");

            A.Parent     = null;
            A.LeftChild  = B;
            A.RightChild = null;

            B.Parent     = A;
            B.LeftChild  = C;
            B.RightChild = D;

            C.Parent     = B;
            C.LeftChild  = null;
            C.RightChild = null;

            D.Parent     = B;
            D.LeftChild  = E;
            D.RightChild = null;

            E.Parent     = D;
            E.LeftChild  = null;
            E.RightChild = null;

            Assert.IsTrue(BinarySearchTreeBaseTests.HasBinarySearchTreeOrderProperty <AVLTreeNode <int, string>, int, string>(A));
            Assert.AreEqual(4, _tree.GetHeight(A));
            Assert.AreEqual(3, _tree.GetHeight(B));
            Assert.AreEqual(1, _tree.GetHeight(C)); // Is a leaf node.
            Assert.AreEqual(2, _tree.GetHeight(D));
            Assert.AreEqual(1, _tree.GetHeight(E)); // Is a leaf node.
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Checks whether the given tree has AVL tree properties
        /// </summary>
        /// <typeparam name="TKey">Type of the keys stored in the tree. </typeparam>
        /// <typeparam name="TValue">Type of the values stored in the tree. </typeparam>
        /// <param name="tree">An AVL tree</param>
        /// <param name="root">Root of the AVL tree</param>
        /// <param name="expectedNodeCount">The expected number of tree nodes in the tree. </param>
        /// <returns>True if the tree has AVL tree properties and false otherwise. </returns>
        public bool HasAVLTreeProperties <TKey, TValue>(AVLTree <TKey, TValue> tree, AVLTreeNode <TKey, TValue> root, int expectedNodeCount) where TKey : IComparable <TKey>, IEquatable <TKey>
        {
            Assert.IsTrue(BinarySearchTreeBaseTests.HasBinarySearchTreeOrderProperty <AVLTreeNode <TKey, TValue>, TKey, TValue>(root));
            var inOrderTraversal = new List <AVLTreeNode <TKey, TValue> >();

            tree.InOrderTraversal(root, inOrderTraversal);
            Assert.AreEqual(expectedNodeCount, inOrderTraversal.Count);
            Assert.IsTrue(HasExpectedBalanceFactor(tree, inOrderTraversal));
            return(true);
        }
        /// <summary>
        /// Checks whether the tree is a proper binary search tree.
        /// </summary>
        /// <param name="tree">A binary search tree. </param>
        /// <param name="root">The root node of the tree. </param>
        /// <param name="expectedTotalKeyCount">Expected total number of keys in the tree. </param>
        public void HasBinarySearchTreeProperties(BinarySearchTreeBase <int, string> tree, BinarySearchTreeNode <int, string> root, int expectedTotalKeyCount)
        {
            Assert.IsTrue(BinarySearchTreeBaseTests.HasBinarySearchTreeOrderProperty <BinarySearchTreeNode <int, string>, int, string>(root));

            var inOrderTraversal = new List <BinarySearchTreeNode <int, string> >();

            tree.InOrderTraversal(root, inOrderTraversal);
            Assert.AreEqual(expectedTotalKeyCount, inOrderTraversal.Count);
            for (int i = 0; i < inOrderTraversal.Count - 1; i++)
            {
                Assert.IsTrue(inOrderTraversal[i].Key < inOrderTraversal[i + 1].Key);
            }
        }
        /// <summary>
        /// Checks whether a tree has a RedBlack tree properties.
        /// </summary>
        /// <typeparam name="TKey">Type of the keys stored in a tree. </typeparam>
        /// <typeparam name="TValue">Type of the values stored in a tree. </typeparam>
        /// <param name="tree">A RedBlack tree. </param>
        /// <param name="root">Root of a RedBlack tree. </param>
        /// <param name="expectedNodeCount">The expected number of nodes in a tree. </param>
        public static void HasRedBlackTreeProperties <TKey, TValue>(RedBlackTree <TKey, TValue> tree, RedBlackTreeNode <TKey, TValue> root, int expectedNodeCount) where TKey : IComparable <TKey>, IEquatable <TKey>
        {
            var inOrderTraversal = new List <RedBlackTreeNode <TKey, TValue> >();

            tree.InOrderTraversal(root, inOrderTraversal);

            // Check order properties.
            Assert.IsTrue(BinarySearchTreeBaseTests.HasBinarySearchTreeOrderProperty <RedBlackTreeNode <TKey, TValue>, TKey, TValue>(root));

            //Check to make sure nodes are not orphaned in the insertion or deletion process.
            Assert.AreEqual(expectedNodeCount, inOrderTraversal.Count);

            // Check color properties.
            if (root != null)
            {
                Assert.IsTrue(root.Color == RedBlackTreeNodeColor.Black);
            }

            foreach (RedBlackTreeNode <TKey, TValue> node in inOrderTraversal)
            {
                Assert.IsTrue(node.Color == RedBlackTreeNodeColor.Red || node.Color == RedBlackTreeNodeColor.Black);

                if (node.Color == RedBlackTreeNodeColor.Red)
                {
                    if (node.LeftChild != null)
                    {
                        Assert.AreEqual(RedBlackTreeNodeColor.Black, node.LeftChild.Color);
                    }
                    if (node.RightChild != null)
                    {
                        Assert.AreEqual(RedBlackTreeNodeColor.Black, node.RightChild.Color);
                    }

                    /* If node N is red, then its parent must be black. As otherwise its parent is red, and the children of a red parent should all be black, in our case node N, which we assumed is red. */
                    Assert.IsTrue(node.Parent.Color == RedBlackTreeNodeColor.Black);
                }
            }

            // all paths from a node to its null (leaf) descendants contain the same number of black nodes.
            foreach (RedBlackTreeNode <TKey, TValue> node in inOrderTraversal)
            {
                List <List <RedBlackTreeNode <TKey, TValue> > > paths = tree.GetAllPathToLeaves(node);
                int shortestPathLength      = int.MaxValue;
                int longestPathLength       = int.MinValue;
                int firstPathBlackNodeCount = 0;
                if (paths.Count >= 0)
                {
                    firstPathBlackNodeCount = paths[0].Count(n => n.Color == RedBlackTreeNodeColor.Black);
                }

                for (int i = 1; i < paths.Count; i++)
                {
                    Assert.AreEqual(firstPathBlackNodeCount, paths[i].Count(n => n.Color == RedBlackTreeNodeColor.Black));
                    if (paths[i].Count > longestPathLength)
                    {
                        longestPathLength = paths[i].Count;
                    }
                    if (paths[i].Count < shortestPathLength)
                    {
                        shortestPathLength = paths[i].Count;
                    }
                }

                // Ensure longest path of a node is not more than twice the shortest path. In the extreme case, shortest path might be all black nodes, and longest path would be alternating between red and black nodes
                Assert.IsTrue(longestPathLength <= 2 * shortestPathLength);
            }
        }