Exemple #1
0
        private void ChangeKeyInternal(
            FibonacciHeapCell <TPriority, TValue> node,
            TPriority NewKey, bool deletingNode)
        {
            Contract.Requires(node != null);

            var delta = Math.Sign(this.priorityComparsion(node.Priority, NewKey));

            if (delta == 0)
            {
                return;
            }
            if (delta == this.DirectionMultiplier || deletingNode)
            {
                //New value is in the same direciton as the heap
                node.Priority = NewKey;
                var parentNode = node.Parent;
                if (parentNode != null && ((priorityComparsion(NewKey, node.Parent.Priority) * DirectionMultiplier) < 0 || deletingNode))
                {
                    node.Marked = false;
                    parentNode.Children.Remove(node);
                    UpdateNodesDegree(parentNode);
                    node.Parent = null;
                    nodes.AddLast(node);
                    //This loop is the cascading cut, we continue to cut
                    //ancestors of the node reduced until we hit a root
                    //or we found an unmarked ancestor
                    while (parentNode.Marked && parentNode.Parent != null)
                    {
                        parentNode.Parent.Children.Remove(parentNode);
                        UpdateNodesDegree(parentNode);
                        parentNode.Marked = false;
                        nodes.AddLast(parentNode);
                        var currentParent = parentNode;
                        parentNode           = parentNode.Parent;
                        currentParent.Parent = null;
                    }
                    if (parentNode.Parent != null)
                    {
                        //We mark this node to note that it's had a child
                        //cut from it before
                        parentNode.Marked = true;
                    }
                }
                //Update next
                if (deletingNode || (priorityComparsion(NewKey, next.Priority) * DirectionMultiplier) < 0)
                {
                    next = node;
                }
            }
            else
            {
                //New value is in opposite direction of Heap, cut all children violating heap condition
                node.Priority = NewKey;
                if (node.Children != null)
                {
                    List <FibonacciHeapCell <TPriority, TValue> > toupdate = null;
                    foreach (var child in node.Children)
                    {
                        if ((priorityComparsion(node.Priority, child.Priority) * DirectionMultiplier) > 0)
                        {
                            if (toupdate == null)
                            {
                                toupdate = new List <FibonacciHeapCell <TPriority, TValue> >();
                            }
                            toupdate.Add(child);
                        }
                    }

                    if (toupdate != null)
                    {
                        foreach (var child in toupdate)
                        {
                            node.Marked = true;
                            node.Children.Remove(child);
                            child.Parent = null;
                            child.Marked = false;
                            nodes.AddLast(child);
                            UpdateNodesDegree(node);
                        }
                    }
                }
                UpdateNext();
            }
        }