private AVLTreeNode <T> InsertInternally(AVLTreeNode <T> rootNode, T key) { // Perform the normal BST insertion if (rootNode == null) { return(new AVLTreeNode <T>(key)); } var compareResult = rootNode.Key.CompareTo(key); if (compareResult > 0) { rootNode.ReplaceLeftNodeWith(InsertInternally((AVLTreeNode <T>)rootNode.Left, key)); } else if (compareResult < 0) { rootNode.ReplaceRightNodeWith(InsertInternally((AVLTreeNode <T>)rootNode.Right, key)); } else // The tree is already contain element { return(rootNode); } // Update height of this ancestor node rootNode.Height = GetMaxValue(GetHeight(rootNode.Left), GetHeight(rootNode.Right)) + 1; // Get the balance factor of this ancestor 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 && rootNode.Left.Key.CompareTo(key) > 0) { return(RightRotate(rootNode)); } // Right Right Case if (balanceFactor < -1 && rootNode.Right.Key.CompareTo(key) < 0) { return(LeftRotate(rootNode)); } // Left Right Case if (balanceFactor > 1 && rootNode.Left.Key.CompareTo(key) < 0) { rootNode.ReplaceLeftNodeWith(LeftRotate((AVLTreeNode <T>)rootNode.Left)); return(RightRotate(rootNode)); } // Right Left Case if (balanceFactor < -1 && rootNode.Right.Key.CompareTo(key) > 0) { rootNode.ReplaceRightNodeWith(RightRotate((AVLTreeNode <T>)rootNode.Right)); return(LeftRotate(rootNode)); } /* return the (unchanged) node pointer */ return(rootNode); }
/// <summary> /// A utility function to left rotate subtree rooted with subtreeRootNode /// </summary> private AVLTreeNode <T> LeftRotate(AVLTreeNode <T> subtreeRootNode) { var rightNode = (AVLTreeNode <T>)subtreeRootNode.Right; var T2 = rightNode.Left; // Perform rotation rightNode.ReplaceLeftNodeWith(subtreeRootNode); subtreeRootNode.ReplaceRightNodeWith(T2); // Update heights subtreeRootNode.Height = GetMaxValue(GetHeight(subtreeRootNode.Left), GetHeight(subtreeRootNode.Right)) + 1; rightNode.Height = GetMaxValue(GetHeight(rightNode.Left), GetHeight(rightNode.Right)) + 1; // Return new root return(rightNode); }
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); }