示例#1
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);
        }
        /// <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);
        }
示例#3
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);
        }
示例#4
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);
        }
示例#5
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);
        }
示例#6
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);
        }
        // Remove the node with the specified key.
        private IAvlNode Remove(object key, IAvlNode node)
        {
            IAvlNode result;

            // The the key does not exist in the SortedList.
            if(node == AvlNode.NullNode)
            {
                // Result is null.
                result = node;
            }
            // Else the key has not yet been found.
            else
            {
                DictionaryEntry entry = (DictionaryEntry)node.Data;
                int compareResult = compareHandler(key, entry.Key);

                // If the specified key is less than the current key.
                if(compareResult < 0)
                {
                    // Create node and continue searching to the left.
                    result = new AvlNode(
                        node.Data,
                        Remove(key, node.LeftChild),
                        node.RightChild);
                }
                // Else if the specified key is greater than the current key.
                else if(compareResult > 0)
                {
                    // Create node and continue searching to the right.
                    result = new AvlNode(
                        node.Data,
                        node.LeftChild,
                        Remove(key, node.RightChild));
                }
                // Else the node to remove has been found.
                else
                {
                    // Remove node.
                    result = node.Remove();                    
                }
            }

            // If the node is out of balance.
            if(!result.IsBalanced())
            {
                // Rebalance node.
                result = result.Balance();
            }

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

            return result;
        }
        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;
        }
示例#9
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);
        }
示例#10
0
        // Left - left single rotation.
        private IAvlNode DoLLRotation(IAvlNode node)
        {
            /*
             *  An LL rotation looks like the following:  
             * 
             *             A          B    
             *            /          / \
             *           B    --->  C   A
             *          /
             *         C 
             */

            // Create right child of the new root.
            IAvlNode a = new AvlNode(
                node.Data, 
                node.LeftChild.RightChild, 
                node.RightChild);

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

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

            return b;
        }
        // Enlarges the tree used by the ArrayList.
        private IAvlNode EnlargeTree()
        {
            // Preconditions.
            Debug.Assert(root.Height <= TreePool.Height);

            // Create new root for the enlarged tree.
            IAvlNode result = new AvlNode(null, root, GetSubTree(root.Height));

            // Postconditions.
            Debug.Assert(result.BalanceFactor == 0);
            Debug.Assert(result.Height == root.Height + 1);

            return result;
        }
示例#12
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;
        }
示例#13
0
        // Finds and removes replacement node for deletion (third case).
        private IAvlNode RemoveReplacement(IAvlNode node, ref IAvlNode replacement)
        {
            IAvlNode newNode;

            // If the bottom of the left tree has been found.
            if(node.LeftChild == AvlNode.NullNode)
            {
                // The replacement node is the node found at this point.
                replacement = node;

                // Get the node's right child. This will be needed as we 
                // ascend back up the tree.
                newNode = node.RightChild;
            }
                // Else the bottom of the left tree has not been found.
            else
            {
                // Create new node and continue descending down the left tree.
                newNode = new AvlNode(node.Data,
                    RemoveReplacement(node.LeftChild, ref replacement),
                    node.RightChild);

                // If the node is out of balance.
                if(!newNode.IsBalanced())
                {
                    // Rebalance the node.
                    newNode = newNode.Balance();
                }
            }

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

            return newNode;
        }
示例#14
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;
        }
        // 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;
        }
        // Adds key/value pair to the internal AVL tree.
        private IAvlNode Add(object key, object value, IAvlNode node)
        {
            IAvlNode result;

            // If the bottom of the tree has been reached.
            if(node == AvlNode.NullNode)
            {
                // Create new node representing the new key/value pair.
                result = new AvlNode(
                    new DictionaryEntry(key, value),
                    AvlNode.NullNode,
                    AvlNode.NullNode);
            }
            // Else the bottom of the tree has not been reached.
            else
            {
                DictionaryEntry entry = (DictionaryEntry)node.Data;
                int compareResult = compareHandler(key, entry.Key);

                // If the specified key is less than the current key.
                if(compareResult < 0)
                {
                    // Create new node and continue searching to the left.
                    result = new AvlNode(
                        node.Data,
                        Add(key, value, node.LeftChild),
                        node.RightChild);
                }
                // Else the specified key is greater than the current key.
                else if(compareResult > 0)
                {
                    // Create new node and continue searching to the right.
                    result = new AvlNode(
                        node.Data,
                        node.LeftChild,
                        Add(key, value, node.RightChild));
                }
                // Else the specified key is equal to the current key.
                else
                {
                    // Throw exception. Duplicate keys are not allowed.
                    throw new ArgumentException(
                        "Item is already in the collection.");
                }
            }

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

            return result;
        }
        // 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;
        }
        // Recursive RemoveAt helper method.
        private IAvlNode RemoveAt(int index, IAvlNode node)
        {
            // Preconditions.
            Debug.Assert(index >= 0 && index < Count);
            Debug.Assert(node != AvlNode.NullNode);

            IAvlNode newNode;

            int leftCount = node.LeftChild.Count;

            // If the node has been found.
            if(index == leftCount)
            {
                newNode = node.Remove();
            }
            // 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.
                newNode = new AvlNode(
                    node.Data,
                    RemoveAt(index, 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.
                newNode = new AvlNode(
                    node.Data,
                    node.LeftChild,
                    RemoveAt(index - (leftCount + 1), node.RightChild));
            }

            // If the node is out of balance.
            if(!newNode.IsBalanced())
            {
                // Rebalance node.
                newNode = newNode.Balance();
            }

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

            return newNode;
        }