/// <summary> /// Remove x from the child list of y. /// </summary> /// <param name="x">A child of y we just decreased the value of.</param> /// <param name="y">The now former parent of x.</param> protected void Cut(FHeapNode <T> x, FHeapNode <T> y) { if (MinItem == null) { throw new InvalidOperationException("Heap malformed"); } if (y.Degree == 1) { y.Child = null; MinItem.AddRight(x); } else if (y.Degree > 1) { x.Remove(); } else { throw new InvalidOperationException("Heap malformed"); } y.Degree--; x.Mark = false; x.Parent = null; }
/// <summary> /// Return the MinItem and remove it from the heap. /// </summary> /// <remarks> /// This function (with all of its helper functions) is the most complicated /// part of the Fibonacci Heap. However, it can be broken down into a few steps. /// <list type="number"> /// <item> /// Add the children of MinItem to the root list. Either one of these children, /// or another of the items in the root list is a candidate to become the new /// MinItem. /// </item> /// <item> /// Remove the MinItem from the root list and appoint a new MinItem temporarily. /// </item> /// <item> /// <see cref="Consolidate" /> what's left /// of the heap. /// </item> /// </list> /// </remarks> /// <returns>The minimum item from the heap.</returns> public T Pop() { FHeapNode <T>?z = null; if (MinItem == null) { throw new InvalidOperationException("Heap is empty!"); } z = MinItem; // Since z is leaving the heap, add its children to the root list if (z.Child != null) { foreach (var x in SiblingIterator(z.Child)) { x.Parent = null; } // This effectively adds each child x to the root list z.ConcatenateRight(z.Child); } if (Count == 1) { MinItem = null; Count = 0; return(z.Key); } // Temporarily reassign MinItem to an arbitrary item in the root // list MinItem = MinItem.Right; // Remove the old MinItem from the root list altogether z.Remove(); // Consolidate the heap Consolidate(); Count -= 1; return(z.Key); }
/// <summary> /// Make y a child of x. /// </summary> /// <param name="y">A node to become the child of x.</param> /// <param name="x">A node to become the parent of y.</param> private void FibHeapLink(FHeapNode <T> y, FHeapNode <T> x) { y.Remove(); x.AddChild(y); y.Mark = false; }