Esempio n. 1
0
 public AVLTreeNode(T value, int height, AVLTreeNode <T> parent, AVLTreeNode <T> left, AVLTreeNode <T> right)
 {
     base.Value = value;
     Height     = height;
     Parent     = parent;
     LeftChild  = left;
     RightChild = right;
 }
Esempio n. 2
0
        private AVLTreeNode <T> RemoveNodeInternally(AVLTreeNode <T> rootNode, T key)
        {
            // Perform standard BST deletion
            if (rootNode == null)
            {
                return(rootNode);
            }

            var compareResult = rootNode.Key.CompareTo(key);

            // If the key to be deleted is smaller than the root's key, then it lies in left subtree
            if (compareResult > 0)
            {
                rootNode.ReplaceLeftNodeWith(RemoveNodeInternally((AVLTreeNode <T>)rootNode.Left, key));
            }

            // If the key to be deleted is greater than the root's key, then it lies in right subtree
            else if (compareResult < 0)
            {
                rootNode.ReplaceRightNodeWith(RemoveNodeInternally((AVLTreeNode <T>)rootNode.Right, key));
            }

            // if key is same as root's key, then this is the node to be deleted
            else
            {
                // node with only one child or no child
                if ((rootNode.Left == null) || (rootNode.Right == null))
                {
                    AVLTreeNode <T> tempNode = null;
                    if (tempNode == rootNode.Left)
                    {
                        tempNode = (AVLTreeNode <T>)rootNode.Right;
                    }
                    else
                    {
                        tempNode = (AVLTreeNode <T>)rootNode.Left;
                    }

                    // No child case
                    if (tempNode == null)
                    {
                        tempNode = rootNode;
                        rootNode = null;
                    }
                    else // One child case
                    {
                        rootNode = tempNode; // Copy the contents of the non-empty child
                    }
                }
                else
                {
                    // node with two children: Get the inorder successor (smallest in the right subtree)
                    AVLTreeNode <T> tempNode = GetMinValueNode((AVLTreeNode <T>)rootNode.Right);

                    // Copy the inorder successor's data to this node
                    rootNode.SetKey(tempNode.Key);

                    // Delete the inorder successor
                    rootNode.ReplaceRightNodeWith(RemoveNodeInternally((AVLTreeNode <T>)rootNode.Right, tempNode.Key));
                }
            }

            // If the tree had only one node then return
            if (rootNode == null)
            {
                return(rootNode);
            }

            // STEP 2: UPDATE HEIGHT OF THE CURRENT NODE
            rootNode.Height = GetMaxValue(GetHeight(rootNode.Left), GetHeight(rootNode.Right)) + 1;

            // STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to check whether this node became unbalanced)
            int balanceFactor = GetBalanceFactor(rootNode);

            // If this node becomes unbalanced, then there are 4 cases
            // Left Left Case
            if (balanceFactor > 1 && GetBalanceFactor((AVLTreeNode <T>)rootNode.Left) >= 0)
            {
                return(RightRotate(rootNode));
            }

            // Left Right Case
            if (balanceFactor > 1 && GetBalanceFactor((AVLTreeNode <T>)rootNode.Left) < 0)
            {
                rootNode.ReplaceLeftNodeWith(LeftRotate((AVLTreeNode <T>)rootNode.Left));
                return(RightRotate(rootNode));
            }

            // Right Right Case
            if (balanceFactor < -1 && GetBalanceFactor((AVLTreeNode <T>)rootNode.Right) <= 0)
            {
                return(LeftRotate(rootNode));
            }

            // Right Left Case
            if (balanceFactor < -1 && GetBalanceFactor((AVLTreeNode <T>)rootNode.Right) > 0)
            {
                rootNode.ReplaceRightNodeWith(RightRotate((AVLTreeNode <T>)rootNode.Right));
                return(LeftRotate(rootNode));
            }

            return(rootNode);
        }