Ejemplo n.º 1
0
        protected N DoDelete(AvlTreeTraversal <N, P> deletionPointLocator)
        {
            N currentNode = deletionPointLocator.CurrentNode;

            Descent direction = deletionPointLocator.Descend();

            if (direction == Descent.NotFound)
            {
                return(null);
            }
            else if (direction == Descent.Found)
            {
                if (currentNode.Left.IsNil)
                {
                    return(currentNode.Right);
                }
                else if (currentNode.Right.IsNil)
                {
                    return(currentNode.Left);
                }
                else // has both children
                {
                    (P payload, N residue) = DeleteMin(currentNode.Right);
                    return(Rebalance(payload, currentNode.Left, residue));
                }
            }
            else
            {
                N left;
                N right;

                if (direction == Descent.Left)
                {
                    left = DoDelete(deletionPointLocator);
                    if (left == null)
                    {
                        return(null); // propagate the 'deletion point not found' result up the stack
                    }

                    right = currentNode.Right;
                }
                else
                {
                    right = DoDelete(deletionPointLocator);
                    if (right == null)
                    {
                        return(null);
                    }

                    left = currentNode.Left;
                }

                return(Rebalance(currentNode.Payload, left, right));
            }
        }
Ejemplo n.º 2
0
        protected N DoInsertOrUpdate(
            P payloadToInsert, Func <P, P> payloadUpdate, AvlTreeTraversal <N, P> nodeLocator)
        {
            N currentNode = nodeLocator.CurrentNode;   // memorize the current node before descending

            Descent direction = nodeLocator.Descend(); // descend: insertionLeafLocator.CurrentNode changes

            if (direction == Descent.NotFound)
            {
                return(null);
            }

            P value;
            N left;
            N right;

            if (direction == Descent.Found)
            {
                if (currentNode.IsNil) // insertion case
                {
                    value = payloadToInsert;
                    left  = NilNode;
                    right = NilNode;
                }
                else // payload replacement case
                {
                    value = payloadUpdate(currentNode.Payload);
                    left  = currentNode.Left;
                    right = currentNode.Right;
                }
            }
            else
            {
                value = currentNode.Payload; // preserve payload
                N rebuiltSubtree = DoInsertOrUpdate(payloadToInsert, payloadUpdate, nodeLocator);
                if (rebuiltSubtree == null)
                {
                    return(null); // propagate the 'insertion/update point not found' result up the stack
                }

                if (direction == Descent.Left)
                {
                    left  = rebuiltSubtree;
                    right = currentNode.Right;
                }
                else // direction == Descent.Right
                {
                    left  = currentNode.Left;
                    right = rebuiltSubtree;
                }
            }

            return(Rebalance(value, left, right));
        }