Ejemplo n.º 1
0
 public void Delete(T data)
 {
     lock (_synchRoot)
     {
         int localCount = _count;
         if (_count > 0)
         {
             bool heightChanged = false;
             //LinkedAvlTreeNode<T> newRoot;
             bool elementDeleted = _root.DeleteElement(data, out _root, out heightChanged);
             if (elementDeleted)
             {
                 _count--;
             }
         }
     }
 }
Ejemplo n.º 2
0
        internal bool DeleteElement(T data, out LinkedAvlTreeNode <T> node, out bool heightDecreased)
        {
            bool deletedLeft    = true;
            bool elementDeleted = false;

            node = this;
            int comparison = this.Data.CompareTo(data);

            if (comparison > 0 && _left != null)
            {
                elementDeleted = _left.DeleteElement(data, out _left, out heightDecreased);
            }
            else if (comparison < 0 && _right != null)
            {
                elementDeleted = _right.DeleteElement(data, out _right, out heightDecreased);
                deletedLeft    = false;
            }
            else if (comparison == 0)
            {
                if (_left == null)
                {
                    UnlinkThis();
                    node = _right; heightDecreased = true;
                    return(true);
                }
                else if (_right == null)
                {
                    UnlinkThis();
                    node = _left; heightDecreased = true;
                    return(true);
                }
                else
                {
                    SwapDataWithNextSmaller(this, this._left);
                    elementDeleted = _left.DeleteElement(data, out _left, out heightDecreased);
                }
            }
            else
            {
                heightDecreased = false;
                return(false);
            }

            if (heightDecreased && deletedLeft)
            {
                if (_balance == 0) // if an element is deleted on the left side, and the node was balanced the node is now taller on the right side
                {                  // but the overall height did not change
                    _balance        = 1;
                    node            = this;
                    heightDecreased = false;
                }
                else if (_balance > 0)        // the right side was already taller; therefore we need to rearrange
                {
                    if (_right._balance == 0) // the left subtree will be higher by one element
                    {
                        _right._balance = -1;
                        _balance        = 1;
                        RotateRight(out node);
                        heightDecreased = false;
                    }
                    else if (_right._balance > 0) // the left subtree grows; therefore the overall size will shrink
                    {
                        _balance        = 0;
                        _right._balance = 0;
                        RotateRight(out node);
                        heightDecreased = true;
                    }
                    else //(_right._balance < 0) // a double rotation is required
                    {
                        DoubleRotateRight(out node);
                        AdjustBalance(node);
                        heightDecreased = true;
                    }
                }
                else // the left subtree was higher; now left and right have the same hight
                {
                    _balance        = 0;
                    node            = this;
                    heightDecreased = true;
                }
            }
            else if (heightDecreased) // deleted right
            {
                if (_balance == 0)    // if an element is deleted on the right side and the node was balanced, the node left subtree is now taller
                {
                    _balance        = -1;
                    node            = this;
                    heightDecreased = false;
                }
                else if (_balance < 0) //the left subtree was taller; we need to rearrange
                {
                    if (_left._balance == 0)
                    {
                        _left._balance = 1;
                        _balance       = -1;
                        RotateLeft(out node);
                        heightDecreased = false;
                    }
                    else if (_left._balance < 0)
                    {
                        _balance       = 0;
                        _left._balance = 0;
                        RotateLeft(out node);
                        heightDecreased = true;
                    }
                    else // left._balance > 0
                    {
                        DoubleRotateLeft(out node);
                        AdjustBalance(node);
                        heightDecreased = true;
                    }
                }
                else
                {
                    _balance        = 0;
                    node            = this;
                    heightDecreased = true;
                }
            }
            else // heigth of subtree did not change!
            {
                node            = this;
                heightDecreased = false;
            }
            return(elementDeleted);
        }