public AVLNode(K Key, V Value, AVLNode <K, V> Parent) : this(Key, Value, Parent, default(int)) { }
/* * Deletion * When a node is deleted from an AVL tree, it must be removed correctly * to make sure the tree remains ordered. The logic to delete a node is * somewhat harder to implement than the code for insertion and I * struggled for a while to understand the AVL algorithm sufficiently * so that I could not only code the delete portion of the tree, but * also ensure it was optimal. * * My implementation of delete considers each edge case separately so * that no unnecessary operations are performed. */ public bool Remove(K key) { AVLNode <K, V> node = Root; while (node != null) { int compare = key.CompareTo(node.Key); if (compare < 0) { node = node.Left; } else if (compare > 0) { node = node.Right; } else { var left = node.Left; var right = node.Right; if (left == null) { if (right == null) { if (node == Root) { Root = null; } else { var parent = node.Parent; if (parent.Left == node) { parent.Left = null; DeleteBalance(parent, -1); } else { parent.Right = null; DeleteBalance(parent, 1); } } } else { Replace(node, right); DeleteBalance(node, 0); } } else if (right == null) { Replace(node, left); DeleteBalance(node, 0); } else { AVLNode <K, V> successor = right; if (successor.Left == null) { AVLNode <K, V> parent = node.Parent; successor.Parent = parent; successor.Left = left; successor.Balance = node.Balance; if (left != null) { left.Parent = successor; } if (node == Root) { Root = successor; } else { if (parent.Left == node) { parent.Left = successor; } else { parent.Right = successor; } } DeleteBalance(successor, 1); } else { while (successor.Left != null) { successor = successor.Left; } AVLNode <K, V> parent = node.Parent; AVLNode <K, V> successorParent = successor.Parent; AVLNode <K, V> successorRight = successor.Right; if (successorParent.Left == successor) { successorParent.Left = successorRight; } else { successorParent.Right = successorRight; } if (successorRight != null) { successorRight.Parent = successorParent; } successor.Parent = parent; successor.Left = left; successor.Balance = node.Balance; successor.Right = right; right.Parent = successor; if (left != null) { left.Parent = successor; } if (node == Root) { Root = successor; } else { if (parent.Left == node) { parent.Left = successor; } else { parent.Right = successor; } } DeleteBalance(successorParent, -1); } } return(true); } } return(false); }