Esempio n. 1
0
        /// <summary>
        /// If the type parameter is <see cref="NoFlip"/>, nodes are iterated from the smallest
        /// to the largest key (left to right); if the parameter is <see cref="DoFlip"/>,
        /// nodes are iterated from the largest to the smallest key (right to left).
        /// </summary>
        internal bool SiftRecursive <T>(NodeTraversalActions <TKey, TValue, BinaryNode <TKey, TValue>, NodeTraversalAction> nodeActions)
            where T : FlipBase <T>
        {
            if (!nodeActions.InvokePreAction(this))
            {
                return(false);
            }

            if (GetLeftChild <T>() != null && !GetLeftChild <T>().SiftRecursive <T>(nodeActions))
            {
                return(false);
            }

            if (!nodeActions.InvokeInAction(this))
            {
                return(false);
            }

            if (GetRightChild <T>() != null && !GetRightChild <T>().SiftRecursive <T>(nodeActions))
            {
                return(false);
            }

            if (!nodeActions.InvokePostAction(this))
            {
                return(false);
            }

            return(true);
        }
Esempio n. 2
0
        private bool HandleSift <T>(
            Stack <NodeTraversalToken <BinaryNode <TKey, TValue>, NodeTraversalAction> > stack,
            NodeTraversalActions <TKey, TValue, BinaryNode <TKey, TValue>, NodeTraversalAction> nodeActions)
            where T : FlipBase <T>
        {
            // First and only visit to this node
            if (!nodeActions.InvokePreAction(this))
            {
                return(false);
            }


            // Push actions in reverse order
            var right = GetRightChild <T>();
            var left  = GetLeftChild <T>();

            if (right != null)
            {
                if (nodeActions.HasPostAction)
                {
                    stack.Push(GetNodeTraversalToken(this, NodeTraversalAction.PostAction));
                }
                stack.Push(GetNodeTraversalToken(right, NodeTraversalAction.Sift));
            }
            else if (left != null && nodeActions.HasPostAction)
            {
                // We need to store the action (it has to be executed after sifting through Left)
                stack.Push(GetNodeTraversalToken(this, NodeTraversalAction.PostAction));
            }

            if (left != null)
            {
                if (nodeActions.HasInAction)
                {
                    stack.Push(GetNodeTraversalToken(this, NodeTraversalAction.InAction));
                }
                stack.Push(GetNodeTraversalToken(left, NodeTraversalAction.Sift));
            }
            else
            {
                // Handle missing children -- we can only invoke actions right away if children are null from left to right
                if (!nodeActions.InvokeInAction(this))
                {
                    return(false);
                }

                if (right == null)
                {
                    if (!nodeActions.InvokePostAction(this))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Esempio n. 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());
        }
Esempio n. 4
0
        /// <summary>
        /// If the type parameter is <see cref="NoFlip"/>, nodes are iterated from the smallest
        /// to the largest key (left to right); if the parameter is <see cref="DoFlip"/>,
        /// nodes are iterated from the largest to the smallest key (right to left).
        /// </summary>
        private bool Sift <T>(NodeTraversalActions <TKey, TValue, BinaryNode <TKey, TValue>, NodeTraversalAction> nodeActions)
            where T : FlipBase <T>
        {
            // We have to use an iterative way because the default stack size of .net apps is 1MB
            // and it's impractical to change it.....
            var stack = nodeActions.TraversalStack;

            Debug.Assert(stack.Count == 0);
            stack.Push(GetNodeTraversalToken(this, NodeTraversalAction.Sift));

            try
            {
                while (stack.Count > 0)
                {
                    var token = stack.Pop();

                    switch (token.Action)
                    {
                    case NodeTraversalAction.Sift:
                        if (!token.Node.HandleSift <T>(stack, nodeActions))
                        {
                            return(false);
                        }
                        break;

                    case NodeTraversalAction.InAction:
                        if (!nodeActions.InvokeInAction(token.Node))
                        {
                            return(false);
                        }
                        break;

                    case NodeTraversalAction.PostAction:
                        if (!nodeActions.InvokePostAction(token.Node))
                        {
                            return(false);
                        }
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }
            finally
            {
                stack.Clear();
            }

            return(true);
        }
Esempio n. 5
0
        /// <summary>
        /// Traverses the binary search tree looking for the searchKey.
        /// If no exact match is found in the tree, returns null.
        /// </summary>
        /// <returns>The first node that matches the <see cref="searchKey"/> or null if the key
        /// is not present in the tree.</returns>
        public BinaryNode <TKey, TValue> Find(TKey searchKey, NodeTraversalActions <TKey, TValue, BinaryNode <TKey, TValue>, NodeTraversalAction> nodeActions)
        {
            // We have to use an iterative way because the default stack size of .net apps is 1MB
            // and it's impractical to change it.....
            var stack = nodeActions.TraversalStack;

            Debug.Assert(stack.Count == 0);
            stack.Push(GetNodeTraversalToken(this, NodeTraversalAction.Sift));

            try
            {
                while (stack.Count > 0)
                {
                    var token = stack.Pop();

                    if (!nodeActions.InvokeKeyPreAction(token.Node, searchKey))
                    {
                        return(null);
                    }


                    int comp = nodeActions.KeyComparer.Compare(searchKey, token.Node.Key);

                    if (comp == 0)
                    {
                        return(token.Node);
                    }

                    var nextNode = comp < 0
                        ? token.Node.LeftChild
                        : token.Node.RightChild;

                    if (nextNode == null)
                    {
                        return(null);
                    }
                    stack.Push(GetNodeTraversalToken(nextNode, NodeTraversalAction.Sift));
                }
            }
            finally
            {
                stack.Clear();
            }

            Debug.Fail("Wth?");
            return(null);
        }
Esempio n. 6
0
        private bool HandleSift(
            Stack <NodeTraversalToken <DisseminateNode <TKey, TValue>, NodeTraversalAction> > stack,
            NodeTraversalActions <TKey, TValue, DisseminateNode <TKey, TValue>, NodeTraversalAction> nodeActions,
            bool addSiblings)
        {
            // First and only visit to this node
            if (!nodeActions.InvokePreAction(this))
            {
                return(false);
            }


            // Push actions in reverse order
            // Push all siblings
            if (addSiblings && RightSibling != this)
            {
                foreach (var siblingNode in GetSiblingsReverse().Where(s => s != this))
                {
                    // Notify that when being sifted, don't try to add all siblings again
                    stack.Push(GetNodeTraversalToken((DisseminateNode <TKey, TValue>)siblingNode, NodeTraversalAction.SiftOnlySiblings));
                }
            }


            // Push the child
            if (FirstChild != null)
            {
                if (nodeActions.HasPostAction)
                {
                    stack.Push(GetNodeTraversalToken(this, NodeTraversalAction.PostAction));
                }

                stack.Push(GetNodeTraversalToken(FirstChild, NodeTraversalAction.Sift));
            }
            else if (!nodeActions.InvokePostAction(this)) // Handle missing children -- we can invoke actions right away
            {
                return(false);
            }

            return(true);
        }
Esempio n. 7
0
        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());
        }
Esempio n. 8
0
        /// <summary>
        /// Traverses the binary search tree looking for the searchKey.
        /// If no exact match is found in the tree, returns null.
        /// </summary>
        /// <returns>The first node that matches the <see cref="searchKey"/> or null if the key
        /// is not present in the tree.</returns>
        internal BinaryNode <TKey, TValue> FindRecursive(TKey searchKey, NodeTraversalActions <TKey, TValue, BinaryNode <TKey, TValue>, NodeTraversalAction> nodeActions)
        {
            if (!nodeActions.InvokeKeyPreAction(this, searchKey))
            {
                return(null);
            }

            int comp = nodeActions.KeyComparer.Compare(searchKey, Key);

            if (comp == 0)
            {
                return(this);
            }

            try
            {
                if (comp < 0)
                {
                    if (LeftChild == null)
                    {
                        return(null);
                    }
                    return(LeftChild.FindRecursive(searchKey, nodeActions));
                }

                if (RightChild == null)
                {
                    return(null);
                }
                return(RightChild.FindRecursive(searchKey, nodeActions));
            }
            finally
            {
                nodeActions.InvokeKeyPostAction(this, searchKey);
            }
        }
Esempio n. 9
0
 /// <summary>
 /// Right DFS traversal of the binary search tree. Nodes are traversed from the largest to the smallest key.
 /// The False return value of the action functions will result in early termination of the traversal.
 /// </summary>
 /// <returns>False if an early termination of the recursion is requested.</returns>
 public bool SiftRight(NodeTraversalActions <TKey, TValue, BinaryNode <TKey, TValue>, NodeTraversalAction> nodeActions)
 {
     return(Sift <DoFlip>(nodeActions));
 }
Esempio n. 10
0
 public SplayTree(IComparer <TKey> keyComparer = null)
 {
     _traversalActions = new NodeTraversalActions <TKey, TValue, BinaryNode <TKey, TValue>, NodeTraversalAction>(keyComparer);
 }
Esempio n. 11
0
 public FibonacciHeap(IComparer <TKey> keyComparer = null)
     : base(keyComparer)
 {
     _traversalActions = new NodeTraversalActions <TKey, TValue, DisseminateNode <TKey, TValue>, NodeTraversalAction>();
 }