/// <summary> /// Add a single node to the tree. /// </summary> /// <param name="key">Key value to add.</param> public void Add(TKey key) { if (root is null) { root = new AvlTreeNode <TKey>(key); } else { root = Add(root, key); } Count++; }
/// <summary> /// Remove a node from the tree. /// </summary> /// <param name="key">Key value to remove.</param> public void Remove(TKey key) { if (root is null) { throw new InvalidOperationException("Tree is empty!"); } else if (!Contains(key)) { throw new KeyNotFoundException($"Key {key} is not in the tree"); } else { root = Remove(root, key); Count--; } }
/// <summary> /// Recursive function to remove node from tree. /// </summary> /// <param name="node">Node to check for key.</param> /// <param name="key">Key value to remove.</param> /// <returns>New node with key removed.</returns> private AvlTreeNode <TKey>?Remove(AvlTreeNode <TKey> node, TKey key) { // Normal binary search tree removal var compareResult = comparer.Compare(key, node.Key); if (compareResult < 0) { node.Left = Remove(node.Left !, key); } else if (compareResult > 0) { node.Right = Remove(node.Right !, key); } else { if (node.Left is null && node.Right is null) { return(null); }
/// <summary> /// Recursively function to add a node to the tree. /// </summary> /// <param name="node">Node to check for null leaf.</param> /// <param name="key">Key value to add.</param> /// <returns>New node with key inserted.</returns> private AvlTreeNode <TKey> Add(AvlTreeNode <TKey> node, TKey key) { // Regular binary search tree insertion int compareResult = comparer.Compare(key, node.Key); if (compareResult < 0) { if (node.Left is null) { var newNode = new AvlTreeNode <TKey>(key); node.Left = newNode; } else { node.Left = Add(node.Left, key); } } else if (compareResult > 0) { if (node.Right is null) { var newNode = new AvlTreeNode <TKey>(key); node.Right = newNode; } else { node.Right = Add(node.Right, key); } } else { throw new ArgumentException($"Key \"{key}\" already exists in tree!"); } // Check all of the new node's ancestors for inbalance and perform // necessary rotations node.UpdateBalanceFactor(); return(Rebalance(node)); }