예제 #1
0
        private void ExtractTree(FibonacciHeapNode <TE, TP> node)
        {
            FibonacciHeapNode <TE, TP> parent = node.Parent;

            // Extract
            node.Parent     = null;
            parent.Children = node.LeftSibling ?? node.RightSibling;
            if (node.LeftSibling != null)
            {
                node.LeftSibling.RightSibling = node.RightSibling;
            }
            if (node.RightSibling != null)
            {
                node.RightSibling.LeftSibling = node.LeftSibling;
            }
            node.LeftSibling  = null;
            node.RightSibling = null;

            // Move to root tree list
            Append(Root, node);

            // If the parent had already lost a child extract it too
            if (parent != null)
            {
                if (parent.HasLostAChild)
                {
                    parent.HasLostAChild = false;
                    ExtractTree(parent);
                }
                else
                {
                    parent.HasLostAChild = true;
                }
            }
        }
예제 #2
0
        public HashSet <FibonacciHeapNode <TE, TP> > GetAllSiblings()
        {
            HashSet <FibonacciHeapNode <TE, TP> > siblings = new HashSet <FibonacciHeapNode <TE, TP> >
            {
                this
            };

            // Find siblings
            FibonacciHeapNode <TE, TP> leftIterator  = LeftSibling;
            FibonacciHeapNode <TE, TP> rightIterator = RightSibling;

            // Enumerate siblings on the left
            while (leftIterator != null)
            {
                siblings.Add(leftIterator);
                leftIterator = leftIterator.LeftSibling;
            }

            // Enumerate siblings on the right
            while (rightIterator != null)
            {
                siblings.Add(rightIterator);
                rightIterator = rightIterator.RightSibling;
            }

            return(siblings);
        }
예제 #3
0
        public FibonacciHeapNode <TE, TP> GetMinimumNodeAmongSibglings()
        {
            FibonacciHeapNode <TE, TP> minimumNode = this;

            // Find minimum
            FibonacciHeapNode <TE, TP> leftIterator  = LeftSibling;
            FibonacciHeapNode <TE, TP> rightIterator = RightSibling;

            // Look for a smaller node on the left
            while (leftIterator != null)
            {
                if (leftIterator.IsSmallerThan(minimumNode))
                {
                    minimumNode = leftIterator;
                }
                leftIterator = leftIterator.LeftSibling;
            }

            // Look for a smaller node on the right
            while (rightIterator != null)
            {
                if (rightIterator.IsSmallerThan(minimumNode))
                {
                    minimumNode = rightIterator;
                }
                rightIterator = rightIterator.RightSibling;
            }

            // Done return smallest node found
            return(minimumNode);
        }
예제 #4
0
        private FibonacciHeapNode <TE, TP> MergeInto(FibonacciHeapNode <TE, TP> root, FibonacciHeapNode <TE, TP> tree)
        {
            // Extract tree to merge from its siblings
            if (tree.LeftSibling != null)
            {
                tree.LeftSibling.RightSibling = tree.RightSibling;
            }
            if (tree.RightSibling != null)
            {
                tree.RightSibling.LeftSibling = tree.LeftSibling;
            }
            tree.LeftSibling  = null;
            tree.RightSibling = null;

            // Merge tree into children of root
            if (root.Children == null)
            {
                root.Children = tree;
            }
            else
            {
                Append(root.Children, tree);
            }
            tree.Parent = root;

            // Return the resulting heap
            return(root);
        }
예제 #5
0
        private void ConsolidateTrees()
        {
            if (Root != null)
            {
                // Keep track of which trees have which rank
                Dictionary <int, FibonacciHeapNode <TE, TP> > RankRoots = new Dictionary <int, FibonacciHeapNode <TE, TP> >();

                // Check each tree
                foreach (FibonacciHeapNode <TE, TP> node in Root.GetAllSiblings())
                {
                    FibonacciHeapNode <TE, TP> newTreeRoot = node;
                    int rank = newTreeRoot.GetRank();

                    // If there is already a tree with the same rank, merge them
                    while (RankRoots.ContainsKey(rank))
                    {
                        FibonacciHeapNode <TE, TP> nodeToLink = RankRoots[rank];
                        RankRoots.Remove(rank);
                        newTreeRoot = MergeHeaps(newTreeRoot, nodeToLink);
                        rank        = newTreeRoot.GetRank();
                    }

                    // The tree - newly merged or not - is currently the only known tree with that rank
                    RankRoots.Add(rank, newTreeRoot);
                }
            }
        }
예제 #6
0
        private void Append(FibonacciHeapNode <TE, TP> heap1, FibonacciHeapNode <TE, TP> heap2)
        {
            var rightEdge = heap1.GetRightmostSibling();
            var leftEdge  = heap2.GetLeftmostSibling();

            rightEdge.RightSibling = leftEdge;
            leftEdge.LeftSibling   = rightEdge;
        }
예제 #7
0
        public (TE, TP) ExtractMinimum()
        {
            if (Empty)
            {
                throw new InvalidOperationException("Heap is empty.");
            }

            // Step 1 - remove minimum element
            // Get minimum node and set root pointer to one of it's siblings (could be null if there are none)
            FibonacciHeapNode <TE, TP> minimumNode = Root;

            Root = minimumNode.LeftSibling ?? minimumNode.RightSibling;

            // Connect siblings, if any
            if (minimumNode.LeftSibling != null)
            {
                minimumNode.LeftSibling.RightSibling = minimumNode.RightSibling;
            }
            if (minimumNode.RightSibling != null)
            {
                minimumNode.RightSibling.LeftSibling = minimumNode.LeftSibling;
            }

            // Merge children into root tree list
            if (minimumNode.Children != null)
            {
                minimumNode.Children.Parent = null;

                // In case the root pointer was null, set it to a child
                if (Root == null)
                {
                    Root = minimumNode.Children;
                }

                // If not merge the children into the root tree list
                else
                {
                    Append(Root, minimumNode.Children);
                }
            }

            // Step 2 - update minimum element if needed
            if (Root != null)
            {
                Root = Root.GetMinimumNodeAmongSibglings();
            }

            // Step 3 - consolidate trees
            ConsolidateTrees();

            // Update count
            Count--;

            // Done, return minimum
            return(minimumNode.Element, minimumNode.Priority);
        }
예제 #8
0
        public FibonacciHeapNode <TE, TP> GetRightmostSibling()
        {
            FibonacciHeapNode <TE, TP> iterator = this;

            while (iterator.RightSibling != null)
            {
                iterator = iterator.RightSibling;
            }

            return(iterator);
        }
예제 #9
0
 private FibonacciHeapNode <TE, TP> MergeHeaps(FibonacciHeapNode <TE, TP> heap1, FibonacciHeapNode <TE, TP> heap2)
 {
     if (heap1.IsSmallerThan(heap2))
     {
         return(MergeInto(heap1, heap2));
     }
     else
     {
         return(MergeInto(heap2, heap1));
     }
 }
예제 #10
0
        public void DecreaseKey(TE element, TP priority)
        {
            FibonacciHeapNode <TE, TP> node = GetNode(element);

            node.Priority = priority;

            // If the heap order is violated, extract the subtree and move it to the main tree list
            if (node.Parent != null && node.IsSmallerThan(node.Parent))
            {
                ExtractTree(node);
            }
            Root = Root.GetMinimumNodeAmongSibglings();
        }
예제 #11
0
        public void Insert(TE element, TP priority)
        {
            var newNode = new FibonacciHeapNode <TE, TP>(element, priority);

            if (Empty)
            {
                Root = newNode;
            }
            else
            {
                Append(Root, newNode);
                if (newNode.IsSmallerThan(Root))
                {
                    Root = newNode;
                }
            }
            Count++;
        }
예제 #12
0
 public bool IsSmallerThan(FibonacciHeapNode <TE, TP> node)
 {
     return(Priority.CompareTo(node.Priority) == -1);
 }