Esempio n. 1
0
        /// <summary>
        /// Initializes the ArrayList class.
        /// </summary>
        static ArrayList()
        {
            IAvlNode parent = AvlNode.NullNode;
            IAvlNode child  = AvlNode.NullNode;

            // Create the tree pool.
            for (int i = 0; i < TreePoolHeight; i++)
            {
                parent = new AvlNode(null, child, child);
                child  = parent;
            }

            TreePool = parent;

            // Postconditions.
            Debug.Assert(TreePool.Height == TreePoolHeight);
        }
Esempio n. 2
0
        private IAvlNode CollectionToTree(IEnumerator enumerator, int height)
        {
            IAvlNode result;

            if (height == 0)
            {
                object data = null;

                if (enumerator.MoveNext())
                {
                    data = enumerator.Current;
                }

                result = new AvlNode(
                    data,
                    AvlNode.NullNode,
                    AvlNode.NullNode);
            }
            else
            {
                IAvlNode leftChild, rightChild;
                object   data = null;

                leftChild = CollectionToTree(enumerator, height - 1);

                if (enumerator.MoveNext())
                {
                    data = enumerator.Current;

                    rightChild = CollectionToTree(enumerator, height - 1);
                }
                else
                {
                    rightChild = GetSubTree(height - 1);
                }

                result = new AvlNode(
                    data,
                    leftChild,
                    rightChild);
            }

            Debug.Assert(result.IsBalanced());

            return(result);
        }
Esempio n. 3
0
        /// <summary>
        /// Removes the current node from the AVL tree.
        /// </summary>
        /// <returns>
        /// The node to in the tree to replace the current node.
        /// </returns>
        public IAvlNode Remove()
        {
            IAvlNode result;

            /*
             * Deal with the three cases for removing a node from a binary tree.
             */

            // If the node has no right children.
            if (this.RightChild == AvlNode.NullNode)
            {
                // The replacement node is the node's left child.
                result = this.LeftChild;
            }
            // Else if the node's right child has no left children.
            else if (this.RightChild.LeftChild == AvlNode.NullNode)
            {
                // The replacement node is the node's right child.
                result = new AvlNode(
                    this.RightChild.Data,
                    this.LeftChild,
                    this.RightChild.RightChild);
            }
            // Else the node's right child has left children.
            else
            {
                /*
                 * Go to the node's right child and descend as far left as
                 * possible. The node found at this point will replace the
                 * node to be removed.
                 */

                IAvlNode replacement = AvlNode.NullNode;
                IAvlNode rightChild  = RemoveReplacement(this.RightChild, ref replacement);

                // Create new node with the replacement node and the new
                // right child.
                result = new AvlNode(
                    replacement.Data,
                    this.LeftChild,
                    rightChild);
            }

            return(result);
        }
Esempio n. 4
0
        // Recursive SetValue helper method.
        private IAvlNode SetValue(int index, object value, IAvlNode node)
        {
            // Preconditions.
            Debug.Assert(index >= 0 && index < node.Count);
            Debug.Assert(node != AvlNode.NullNode);

            IAvlNode result;
            int      leftCount = node.LeftChild.Count;

            // If the node has been found.
            if (index == leftCount)
            {
                // Create new node with the new value.
                result = new AvlNode(value, node.LeftChild, node.RightChild);
            }
            // Else if the node is in the left tree.
            else if (index < leftCount)
            {
                // Create new node and move search to the left child. The new
                // node will reuse the right child subtree.
                result = new AvlNode(
                    node.Data,
                    SetValue(index, value, node.LeftChild),
                    node.RightChild);
            }
            // Else if the node is in the right tree.
            else
            {
                // Create new node and move search to the right child. The new
                // node will reuse the left child subtree.
                result = new AvlNode(
                    node.Data,
                    node.LeftChild,
                    SetValue(index - (leftCount + 1), value, node.RightChild));
            }

            return(result);
        }
Esempio n. 5
0
        // Right - left double rotation.
        private IAvlNode DoRLRotation(IAvlNode node)
        {
            /*
             *  An RL rotation looks like the following:
             *
             *       Perform an LL rotation at B:
             *
             *         A            A
             *          \            \
             *           B    --->    C
             *          /              \
             *         C                B
             *
             *       Perform an RR rotation at A:
             *
             *         A              C
             *          \            / \
             *           C    --->  A   B
             *            \
             *             B
             */

            IAvlNode a = new AvlNode(
                node.Data,
                node.LeftChild,
                DoLLRotation(node.RightChild));

            IAvlNode c = DoRRRotation(a);

            // Postconditions.
            Debug.Assert(c.Data == node.RightChild.LeftChild.Data);
            Debug.Assert(c.LeftChild.Data == node.Data);
            Debug.Assert(c.RightChild.Data == node.RightChild.Data);

            return(c);
        }
Esempio n. 6
0
        // Recursive Insert helper method.
        private IAvlNode Insert(int index, object value, IAvlNode node)
        {
            // Preconditions.
            Debug.Assert(index >= 0 && index <= Count);
            Debug.Assert(node != null);

            /*
             * The insertion algorithm searches for the correct place to add a
             * new node at the bottom of the tree using the specified index.
             */

            IAvlNode result;

            // If the bottom of the tree has not yet been reached.
            if (node != AvlNode.NullNode)
            {
                int leftCount = node.LeftChild.Count;

                // If we need to descend to the left.
                if (index <= leftCount)
                {
                    // Create new node and move search to the left child. The
                    // new node will reuse the right child subtree.
                    result = new AvlNode(
                        node.Data,
                        Insert(index, value, node.LeftChild),
                        node.RightChild);
                }
                // Else we need to descend to the right.
                else
                {
                    // Create new node and move search to the right child. The
                    // new node will reuse the left child subtree.
                    result = new AvlNode(
                        node.Data,
                        node.LeftChild,
                        Insert(index - (leftCount + 1),
                               value,
                               node.RightChild));
                }
            }
            // Else the bottom of the tree has been reached.
            else
            {
                // Create new node at the specified index.
                result = new AvlNode(value, AvlNode.NullNode, AvlNode.NullNode);
            }

            /*
             * This check isn't necessary if a node has already been rebalanced
             * after an insertion. AVL tree insertions never require more than
             * one rebalancing. However, it's easier to go ahead and check at
             * this point since we're using recursion. This may need optimizing
             * in the future.
             */

            // If the node is not balanced.
            if (!result.IsBalanced())
            {
                // Rebalance node.
                result = result.Balance();
            }

            // Postconditions.
            Debug.Assert(result.IsBalanced());

            return(result);
        }