private void RightRotation()
        {
            //     c (this)
            //    /
            //   b
            //  /
            // a
            //
            // becomes
            //       b
            //      / \
            //     a   c

            // Note: RightRotation is basically the opposite of LeftRotation

            AVLTreeNode <TNode> newRoot = Left;

            // replace the current root with the new root
            ReplaceRoot(newRoot);
            // take ownership of left's right child as left (now parent)
            Left = newRoot.Right;
            // the new root takes this as it's right
            newRoot.Right = this;
        }
예제 #2
0
        public bool Remove(T value)
        {
            AVLTreeNode <T> current;

            current = Find(value);

            if (current == null)
            {
                return(false);
            }

            AVLTreeNode <T> treeToBalance = current.Parent;

            Count--;

            if (current.Right == null)
            {
                if (current.Parent == null)
                {
                    Head = current.Left;

                    if (Head != null)
                    {
                        Head.Parent = null;
                    }
                }
                else
                {
                    int result = current.Parent.CompareTo(current.Value);

                    if (result > 0)
                    {
                        current.Parent.Left = current.Left;
                    }
                    else if (result < 0)
                    {
                        current.Parent.Right = current.Left;
                    }
                }
            }
            else if (current.Right.Left == null)
            {
                current.Right.Left = current.Left;
                if (current.Parent == null)
                {
                    Head = current.Right;

                    if (Head != null)
                    {
                        Head.Parent = null;
                    }
                }
                else
                {
                    int result = current.Parent.CompareTo(current.Value);

                    if (result > 0)
                    {
                        current.Parent.Left = current.Right;
                    }
                    else if (result < 0)
                    {
                        current.Parent.Right = current.Right;
                    }
                }
            }
            else
            {
                AVLTreeNode <T> leftmost = current.Right.Left;

                while (leftmost.Left != null)
                {
                    leftmost = leftmost.Left;
                }

                leftmost.Parent.Left = leftmost.Right;
                leftmost.Left        = current.Left;
                leftmost.Right       = current.Right;

                if (current.Parent == null)
                {
                    Head = leftmost;

                    if (Head != null)
                    {
                        Head.Parent = null;
                    }
                }
                else
                {
                    int result = current.Parent.CompareTo(current.Value);

                    if (result > 0)
                    {
                        current.Parent.Left = leftmost;
                    }
                    else if (result < 0)
                    {
                        current.Parent.Right = leftmost;
                    }
                }
            }

            if (treeToBalance != null)
            {
                treeToBalance.Balance();
            }
            else
            {
                if (Head != null)
                {
                    Head.Balance();
                }
            }

            return(true);
        }
예제 #3
0
        public bool Remove(T value)
        {
            AVLTreeNode <T> current;

            current = Find(value); // находим узел с удаляемым значением

            if (current == null)   // узел не найден
            {
                return(false);
            }

            AVLTreeNode <T> treeToBalance = current.Parent; // баланс дерева относительно узла родителя

            Count--;                                        // уменьшение колиества узлов

            // Вариант 1: Если удаляемый узел не имеет правого потомка

            if (current.Right == null)      // если нет правого потомка
            {
                if (current.Parent == null) // удаляемый узел является корнем
                {
                    Head = current.Left;    // на место корня перемещаем левого потомка

                    if (Head != null)
                    {
                        Head.Parent = null; // убераем ссылку на родителя
                    }
                }
                else // удаляемый узел не является корнем
                {
                    int result = current.Parent.CompareTo(current.Value);

                    if (result > 0)
                    {
                        // Если значение родительского узла больше значения удаляемого,
                        // сделать левого потомка удаляемого узла, левым потомком родителя.

                        current.Parent.Left = current.Left;
                    }
                    else if (result < 0)
                    {
                        // Если значение родительского узла меньше чем удаляемого,
                        // сделать левого потомка удаляемого узла - правым потомком родительского узла.

                        current.Parent.Right = current.Left;
                    }
                }
            }

            // Вариант 2: Если правый потомок удаляемого узла не имеет левого потомка, тогда правый потомок удаляемого узла
            // становится потомком родительского узла.

            else if (current.Right.Left == null) // если у правого потомка нет левого потомка
            {
                current.Right.Left = current.Left;

                if (current.Parent == null) // текущий элемент является корнем
                {
                    Head = current.Right;

                    if (Head != null)
                    {
                        Head.Parent = null;
                    }
                }
                else
                {
                    int result = current.Parent.CompareTo(current.Value);
                    if (result > 0)
                    {
                        // Если значение узла родителя больше чем значение удаляемого узла,
                        // сделать правого потомка удаляемого узла, левым потомком его родителя.

                        current.Parent.Left = current.Right;
                    }

                    else if (result < 0)
                    {
                        // Если значение родительского узла меньше значения удаляемого,
                        // сделать правого потомка удаляемого узла - правым потомком родителя.

                        current.Parent.Right = current.Right;
                    }
                }
            }

            // Вариант 3: Если правый потомок удаляемого узла имеет левого потомка,
            // заместить удаляемый узел, крайним левым потомком правого потомка.
            else
            {
                // Нахожление крайнего левого узла для правого потомка удаляемого узла.

                AVLTreeNode <T> leftmost = current.Right.Left;

                while (leftmost.Left != null)
                {
                    leftmost = leftmost.Left;
                }

                // Родительское правое поддерево становится родительским левым поддеревом.

                leftmost.Parent.Left = leftmost.Right;

                // Присвоить крайнему левому узлу, ссылки на правого и левого потомка удаляемого узла.
                leftmost.Left  = current.Left;
                leftmost.Right = current.Right;

                if (current.Parent == null)
                {
                    Head = leftmost;

                    if (Head != null)
                    {
                        Head.Parent = null;
                    }
                }
                else
                {
                    int result = current.Parent.CompareTo(current.Value);

                    if (result > 0)
                    {
                        // Если значение родительского узла больше значения удаляемого,
                        // сделать крайнего левого потомка левым потомком родителя удаляемого узла.

                        current.Parent.Left = leftmost;
                    }
                    else if (result < 0)
                    {
                        // Если значение родительского узла, меньше чем значение удаляемого,
                        // сделать крайнего левого потомка, правым потомком родителя удаляемого узла.

                        current.Parent.Right = leftmost;
                    }
                }
            }

            if (treeToBalance != null)
            {
                treeToBalance.Balance();
            }

            else
            {
                if (Head != null)
                {
                    Head.Balance();
                }
            }

            return(true);
        }
 /// <summary>
 /// Removes all items from the tree
 /// </summary>
 public void Clear()
 {
     _head  = null;
     _count = 0;
 }
        /// <summary>
        /// Removes the first occurance of the specified value from the tree.
        /// </summary>
        /// <param name="value">The value to remove</param>
        /// <returns>True if the value was removed, false otherwise</returns>
        public bool Remove(T value)
        {
            AVLTreeNode <T> current;

            // Find the node to remove
            current = Find(value);
            // If no such node, then just return false
            if (current == null)
            {
                return(false);
            }

            AVLTreeNode <T> treeToBalance = current.Parent;

            _count--;

            // Case 1: If current has no right child, then
            // current's left replaces current
            if (current.Right == null)
            {
                // The node to be removed is the head node
                if (current.Parent == null)
                {
                    _head = current.Left;
                    if (_head != null)
                    {
                        _head.Parent = null;
                    }
                }
                else
                {
                    // This is to determine after the current's left replaces current,
                    // it should be the left child or the right child of current's parent node.
                    int result = current.Parent.CompareTo(current.Value);
                    if (result > 0)
                    {
                        // if parent value is greater than current value
                        // make the current's left child a left child of parent
                        current.Parent.Left = current.Left;
                    }
                    else if (result < 0)
                    {
                        // if parent value is less than current value
                        // make the current's left child a right child of parent
                        current.Parent.Right = current.Left;
                    }
                }
            }
            // Case 2: If current's right child has no left child, then current's
            // right child replaces current
            // first we move current's left child to its right child's left child since it has no left child.
            // the reason we can do this is because current's right must be bigger than current, but
            // current's left must be smaller than current, so it's safe to make such move.
            else if (current.Right.Left == null)
            {
                current.Right.Left = current.Left;
                if (current.Parent == null)
                {
                    _head = current.Right;
                    if (_head != null)
                    {
                        _head.Parent = null;
                    }
                }
                else
                {
                    int result = current.Parent.CompareTo(current.Value);
                    if (result > 0)
                    {
                        // if parent value is greater than current value
                        // make the current's right child a left child of parent
                        current.Parent.Left = current.Right;
                    }
                    else if (result < 0)
                    {
                        // if parent value is less than current value
                        // make the current right child a right child of parent
                        current.Parent.Right = current.Right;
                    }
                }
            }
            // Case 3: current's right has a left child, then replace current with current's
            //         right child's left-most child.
            // Seems complicated but the reason is actually straightforward.
            // Current's right must be bigger than current, and current's right's left-most node
            // must be the least bigger value compared to current, so it needs to be replaced by
            // that value.
            else
            {
                // Find the right's left-most child
                // start with current.Right.Left as first
                AVLTreeNode <T> leftmost = current.Right.Left;
                while (leftmost.Left != null)
                {
                    leftmost = leftmost.Left;
                }
                // if the leftmost node has a right child, make that right child
                // as leftmost's parent's left child
                leftmost.Parent.Left = leftmost.Right;
                // assign leftmost's left and right to current's left and right children
                leftmost.Left  = current.Left;
                leftmost.Right = current.Right;

                if (current.Parent == null)
                {
                    _head = leftmost;
                    if (_head != null)
                    {
                        _head.Parent = null;
                    }
                }
                else
                {
                    int result = current.Parent.CompareTo(current.Value);
                    if (result > 0)
                    {
                        // if parent value is greater than current value
                        // make leftmost the parent's left child
                        current.Parent.Left = leftmost;
                    }
                    else if (result < 0)
                    {
                        // if parent value is less than current value
                        // make leftmost the parent's right child
                        current.Parent.Right = leftmost;
                    }
                }
            }

            // Removal done, need to consider balancing

            if (treeToBalance != null)
            {
                treeToBalance.Balance();
            }
            else
            {
                if (_head != null)
                {
                    _head.Balance();
                }
            }

            return(true);
        }
예제 #6
0
        //Vi node la dai luong nguoi dung khoi tao nen cac phep toan so sanh phari duoc cai dat
        public int CompareTo(object obj)
        {
            AVLTreeNode <T> node = obj as AVLTreeNode <T>;

            return(this.Value.CompareTo(node.Value));
        }
예제 #7
0
        private AVLTreeNode <T> Remove(AVLTreeNode <T> node, T value)
        {
            //Neu cay rong
            if (node == null)
            {
                return(null);
            }

            else
            {
                AVLTreeNode <T> parent = new AVLTreeNode <T>(value);
                if (node.Value.CompareTo(value) > 0)//Truong hop gia tri can xoa nho hon node dang xet->tim tren cay con trai
                {
                    node.LeftChild = Remove(node.LeftChild, value);
                    if (balance_factor(node) == -2)//Cay lech phai
                    {
                        if (balance_factor(node.RightChild) <= 0)
                        {
                            node = RotateRR(node);
                        }
                        else
                        {
                            node = RotateRL(node);
                        }
                    }
                }
                else if (node.Value.CompareTo(value) < 0)//Truong hop gia tri can xoa lon hon node dang xet->tim tren cayy con phai
                {
                    node.RightChild = Remove(node.RightChild, value);
                    if (balance_factor(node) == 2)//Cay lech trai
                    {
                        if (balance_factor(node.LeftChild) >= 0)
                        {
                            node = RotateLL(node);
                        }
                        else
                        {
                            node = RotateLR(node);
                        }
                    }
                }
                ///Neu tim duoc nodee can xet
                else
                {
                    if (node.RightChild != null)
                    {
                        //delete its inorder successor
                        parent = node.RightChild;
                        while (parent.LeftChild != null)
                        {
                            parent = parent.LeftChild;
                        }
                        node.Value      = parent.Value; //Gan lai gia tri node hien hanh
                        node.RightChild = Remove(node.RightChild, parent.Value);
                        if (balance_factor(node) == 2)  //Tai can bang cay
                        {
                            if (balance_factor(node.LeftChild) >= 0)
                            {
                                node = RotateLL(node);
                            }
                            else
                            {
                                node = RotateLR(node);
                            }
                        }
                    }
                    else
                    {   //if node.left != null
                        return(node.LeftChild);
                    }
                }
            }
            return(node);
        }
예제 #8
0
        private bool CheckRemove(AVLTreeNode <T> node, T value)
        {
            if (node == null)
            {
                return(false);
            }

            if (node.Value.Equals(value))
            {
                if (node.IsLeaf) // no children
                {
                    if (node.Parent.LeftChild == node)
                    {
                        node.Parent.LeftChild = null;
                    }
                    else
                    {
                        node.Parent.RightChild = null;
                    }

                    node.Parent = null;
                }
                else if (node.CheckLeftChild && node.CheckRightChild)   // 2 children
                {
                    // Tìm successor node
                    AVLTreeNode <T> replacementNode = node.RightChild;

                    while (replacementNode.CheckLeftChild)
                    {
                        replacementNode = replacementNode.LeftChild;
                    }
                    node.Value = replacementNode.Value;

                    Remove(replacementNode, replacementNode.Value);
                }
                else    // one child
                {
                    AVLTreeNode <T> subNode;

                    if (node.CheckLeftChild)
                    {
                        subNode = node.LeftChild;
                    }
                    else
                    {
                        subNode = node.RightChild;
                    }

                    if (Root == (subNode))
                    {
                        Root = subNode;
                    }

                    subNode.Parent = node.Parent;

                    if (node.Parent.LeftChild == node)
                    {
                        node.Parent.LeftChild = subNode;
                    }
                    else
                    {
                        node.Parent.RightChild = subNode;
                    }
                }

                return(true);
            }
            else
            {
                if (node.Value.CompareTo(value) > 0)
                {
                    return(CheckRemove(node.LeftChild, value));
                }
                else
                {
                    return(CheckRemove(node.RightChild, value));
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Removes the first occurance of the specified value from the tree.
        /// </summary>
        /// <param name="value">The value to remove</param>
        /// <returns>True if the value was removed, false otherwise</returns>
        public bool Remove(T value)
        {
            var current = Find(value);

            if (current == null)
            {
                return(false);
            }

            var treeToBalance = current.Parent;

            Count--;

            // Case 1: If current has no right child, then current's left replaces current
            if (current.Right == null)
            {
                if (current.Parent == null)
                {
                    _head = current.Left;
                    if (_head != null)
                    {
                        _head.Parent = null;
                    }
                }
                else
                {
                    var result = current.Parent.CompareTo(current.Value);
                    if (result > 0)
                    {
                        // if parent value is greater than current value make the current left child a left child of parent
                        current.Parent.Left = current.Left;
                    }
                    else if (result < 0)
                    {
                        // if parent value is less than current value make the current left child a right child of parent
                        current.Parent.Right = current.Left;
                    }
                }
            }
            // Case 2: If current's right child has no left child, then current's right child
            //         replaces current
            else if (current.Right.Left == null)
            {
                current.Right.Left = current.Left;

                if (current.Parent == null)
                {
                    _head = current.Right;
                    if (_head != null)
                    {
                        _head.Parent = null;
                    }
                }
                else
                {
                    var result = current.Parent.CompareTo(current.Value);
                    if (result > 0)
                    {
                        // if parent value is greater than current value make the current right child a left child of parent
                        current.Parent.Left = current.Right;
                    }
                    else if (result < 0)
                    {
                        // if parent value is less than current value make the current right child a right child of parent
                        current.Parent.Right = current.Right;
                    }
                }
            }
            // Case 3: If current's right child has a left child, replace current with current's
            //         right child's left-most child
            else
            {
                // find the right's left-most child
                var leftmost = current.Right.Left;

                while (leftmost.Left != null)
                {
                    leftmost = leftmost.Left;
                }

                // the parent's left subtree becomes the leftmost's right subtree
                leftmost.Parent.Left = leftmost.Right;

                // assign leftmost's left and right to current's left and right children
                leftmost.Left  = current.Left;
                leftmost.Right = current.Right;

                if (current.Parent == null)
                {
                    _head = leftmost;
                    if (_head != null)
                    {
                        _head.Parent = null;
                    }
                }
                else
                {
                    var result = current.Parent.CompareTo(current.Value);
                    if (result > 0)
                    {
                        // if parent value is greater than current value make leftmost the parent's left child
                        current.Parent.Left = leftmost;
                    }
                    else if (result < 0)
                    {
                        // if parent value is less than current value make leftmost the parent's right child
                        current.Parent.Right = leftmost;
                    }
                }
            }

            if (treeToBalance != null)
            {
                treeToBalance.Balance();
            }
            else
            {
                _head?.Balance();
            }

            return(true);
        }
예제 #10
0
 public AVLTreeNode(TNode value, AVLTreeNode <TNode> parent, AVLTree <TNode> tree)
 {
     Value  = value;
     Parent = parent;
     _tree  = tree;
 }
예제 #11
0
            public bool Remove(T value)
            {
                var compare = value.CompareTo(Value);

                if (compare == 0)
                {
                    if (LeftHand == null && RightHand == null)
                    {
                        if (Parent != null)
                        {
                            if (Parent.LeftHand == this)
                            {
                                Parent.LeftHand = null;
                            }
                            else
                            {
                                Parent.RightHand = null;
                            }

                            Parent.Reconstruct(true);
                        }
                        else
                        {
                            AVLTree.RootNode = null;
                        }
                    }
                    else
                    {
                        if (LeftHand == null || RightHand == null)
                        {
                            AVLTreeNode child = LeftHand ?? RightHand;

                            if (Parent != null)
                            {
                                if (Parent.LeftHand == this)
                                {
                                    Parent.LeftHand = child;
                                }
                                else
                                {
                                    Parent.RightHand = child;
                                }

                                child.Parent = Parent;
                                child.Parent.Reconstruct(true);
                            }
                            else
                            {
                                AVLTree.RootNode        = child;
                                AVLTree.RootNode.Parent = null;
                            }
                        }
                        else
                        {
                            AVLTreeNode replace = LeftHand;

                            while (replace.RightHand != null)
                            {
                                replace = replace.RightHand;
                            }

                            T tempValue = Value;
                            Value         = replace.Value;
                            replace.Value = tempValue;

                            return(replace.Remove(replace.Value));
                        }
                    }

                    Parent = LeftHand = RightHand = null;
                    return(true);
                }

                if (compare < 0)
                {
                    return(LeftHand == null ? false : LeftHand.Remove(value));
                }
                else
                {
                    return(RightHand == null ? false : RightHand.Remove(value));
                }
            }
예제 #12
0
            void Reconstruct(bool recursive)
            {
                Count = 1;

                int leftLevel  = 0;
                int rightLevel = 0;

                if (LeftHand != null)
                {
                    leftLevel = LeftHand.Level;
                    Count    += LeftHand.Count;
                }

                if (RightHand != null)
                {
                    rightLevel = RightHand.Level;
                    Count     += RightHand.Count;
                }

                if (leftLevel - rightLevel > 1)
                {
                    int leftNext  = LeftHand.LeftHand == null ? 0 : LeftHand.LeftHand.Level;
                    int rightNext = LeftHand.RightHand == null ? 0 : LeftHand.RightHand.Level;

                    if (leftNext >= rightNext)
                    {
                        LeftHand.Elevate();
                        Reconstruct(true);
                    }
                    else
                    {
                        AVLTreeNode pivot = LeftHand.RightHand;

                        pivot.Elevate();
                        pivot.Elevate();

                        pivot.LeftHand.Reconstruct(false);
                        pivot.RightHand.Reconstruct(true);
                    }
                }
                else if (rightLevel - leftLevel > 1)
                {
                    int leftNext  = RightHand.LeftHand == null ? 0 : RightHand.LeftHand.Level;
                    int rightNext = RightHand.RightHand == null ? 0 : RightHand.RightHand.Level;

                    if (rightNext >= leftNext)
                    {
                        RightHand.Elevate();
                        Reconstruct(true);
                    }
                    else
                    {
                        var pivot = RightHand.LeftHand;

                        pivot.Elevate();
                        pivot.Elevate();

                        pivot.LeftHand.Reconstruct(false);
                        pivot.RightHand.Reconstruct(true);
                    }
                }
                else
                {
                    Level = Math.Max(leftLevel, rightLevel) + 1;

                    if (Parent != null && recursive)
                    {
                        Parent.Reconstruct(true);
                    }
                }
            }