public override bool Remove(TKey key) { if (!Splay(key)) { return(false); } // Root is now the node to be removed Debug.Assert(Root != null); BinaryNode <TKey, TValue> leftTree = Root.LeftChild; // 1. If the root's left subtree is empty, the root will start with the right subtree if (leftTree == null) { BinaryNode <TKey, TValue> oldRoot = Root; Root = oldRoot.RightChild; if (Root != null) { Root.Parent = null; } oldRoot.Dispose(); Count--; return(true); } // 2. Find the right-most node in the root's left subtree -- it will become the new root BinaryNode <TKey, TValue> rightMost = null; _traversalActions.SetActions(inAction: n => { rightMost = n; return(false); // Terminate the DFS when we find the first node }); leftTree.SiftRight(_traversalActions); Debug.Assert(rightMost != null); // Count > 0: there should be at least the root // 3. Splay the right-most node // Remove the parent of root's left child to not splay up to root leftTree.Parent = null; rightMost.Splay(out Root, out LastSplayDepth); // 4. Right-most is now root of the left tree (and has no right subtree); merge it with Root leftTree = rightMost; Debug.Assert(leftTree.RightChild == null); // Splay on the right-most node should make it have no right (larger) children leftTree.RightChild = Root.RightChild; if (leftTree.RightChild != null) { leftTree.RightChild.Parent = leftTree; } Root.Clear(); Root = leftTree; Count--; return(true); }