/// <summary> /// Performs the set operation on a given data structure. /// </summary> private static SortedInt32KeyNode <HashBucket> UpdateRoot(SortedInt32KeyNode <HashBucket> root, int hashCode, IEqualityComparer <HashBucket> hashBucketEqualityComparer, HashBucket newBucket) { bool mutated; if (newBucket.IsEmpty) { return(root.Remove(hashCode, out mutated)); } else { return(root.SetItem(hashCode, newBucket, hashBucketEqualityComparer, out bool replacedExistingValue, out mutated)); } }
/// <summary> /// Removes the specified key. Callers are expected to validate arguments. /// </summary> /// <param name="key">The key.</param> /// <param name="mutated">Receives a value indicating whether this node tree has mutated because of this operation.</param> /// <returns>The new AVL tree.</returns> private SortedInt32KeyNode <TValue> RemoveRecursive(int key, out bool mutated) { if (this.IsEmpty) { mutated = false; return(this); } else { SortedInt32KeyNode <TValue> result = this; if (key == _key) { // We have a match. mutated = true; // If this is a leaf, just remove it // by returning Empty. If we have only one child, // replace the node with the child. if (_right.IsEmpty && _left.IsEmpty) { result = EmptyNode; } else if (_right.IsEmpty && !_left.IsEmpty) { result = _left; } else if (!_right.IsEmpty && _left.IsEmpty) { result = _right; } else { // We have two children. Remove the next-highest node and replace // this node with it. var successor = _right; while (!successor._left.IsEmpty) { successor = successor._left; } bool dummyMutated; var newRight = _right.Remove(successor._key, out dummyMutated); result = successor.Mutate(left: _left, right: newRight); } } else if (key < _key) { var newLeft = _left.Remove(key, out mutated); if (mutated) { result = this.Mutate(left: newLeft); } } else { var newRight = _right.Remove(key, out mutated); if (mutated) { result = this.Mutate(right: newRight); } } return(result.IsEmpty ? result : MakeBalanced(result)); } }