示例#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);
        }
示例#2
0
        public override void Clear()
        {
            if (Count == 0)
            {
                return;
            }

            _traversalActions.SetActions(postAction: n =>
            {
                n.Dispose();
                return(true);
            });

            // Start Dispose from the last node (postAction)
            _consolidateRoots.Sift(_traversalActions);

            foreach (var root in GetRoots())
            {
                root.Sift(_traversalActions);
            }

            _roots.Clear();
            _minNode          = null;
            _consolidateRoots = null;
            Count             = 0;
        }
示例#3
0
        public override string ToString()
        {
            StringBuilder prefix = new StringBuilder();
            StringBuilder sb     = new StringBuilder();

            NodeTraversalActions <TKey, TValue, BinaryNode <TKey, TValue>, NodeTraversalAction> .NodeTraversalAction preAction = node =>
            {
                Debug.Assert(node == this || node.Parent != null);

                // Compute new prefix for the right child
                prefix.Append(node.Parent != null && node.IsLeftChild() ? ExtendPrefix : EmptyPrefix);
                return(true);
            };

            NodeTraversalActions <TKey, TValue, BinaryNode <TKey, TValue>, NodeTraversalAction> .NodeTraversalAction inAction = node =>
            {
                // Get the old prefix (revert the preAction)
                prefix.Length -= ExtendPrefix.Length;

                bool isLeftChild = node.Parent == null || node.IsLeftChild();

                // Output a new line
                sb.Append(prefix);
                if (node.Parent == null)
                {
                    sb.Append(RootFork);
                }
                else
                {
                    sb.Append(isLeftChild ? LeftFork : RightFork);
                }
                sb.AppendLine(node.Key.ToString());

                // Compute new prefix for the left child
                prefix.Append(isLeftChild ? EmptyPrefix : ExtendPrefix);
                return(true);
            };

            NodeTraversalActions <TKey, TValue, BinaryNode <TKey, TValue>, NodeTraversalAction> .NodeTraversalAction postAction = node =>
            {
                // Get the old prefix (revert the inAction)
                prefix.Length -= ExtendPrefix.Length;
                return(true);
            };

            var nodeActions = new NodeTraversalActions <TKey, TValue, BinaryNode <TKey, TValue>, NodeTraversalAction>(); // We do not need to pass the owner's comparer -- Sift does not use it (only Find does)

            nodeActions.SetActions(preAction, inAction, postAction);
            SiftRight(nodeActions);

            return(sb.ToString());
        }
        public string ToString(NodeTraversalActions <TKey, TValue, DisseminateNode <TKey, TValue>, NodeTraversalAction> traversalActions)
        {
            var sb     = new StringBuilder();
            var indent = new StringBuilder();

            const string ind = "   ";

            traversalActions.SetActions(preAction: node =>
            {
                indent.Append(ind);
                sb.Append(indent);
                sb.AppendLine(node.ToString());
                return(true);
            },
                                        postAction: node =>
            {
                indent.Length -= ind.Length;
                return(true);
            });

            Sift(traversalActions);
            return(sb.ToString());
        }