Esempio n. 1
0
        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);
        }