/// <summary> /// Update the Heap with new value for this node pointer /// O(1) complexity amortized /// </summary> /// <param name="key"></param> public void DecrementKey(FibornacciHeapNode <T> node) { if (node.Parent == null && minNode.Value.CompareTo(node.Value) > 0) { minNode = node; } var current = node; if (current.Parent != null && current.Value.CompareTo(current.Parent.Value) < 0) { var parent = current.Parent; //if parent already lost one child //then cut current and parent if (parent.LostChild) { parent.LostChild = false; var grandParent = parent.Parent; //mark grand parent if (grandParent != null) { Cut(parent); Cut(current); } } else { Cut(current); } } }
/// <summary> /// Merge roots with same degrees in Forest /// </summary> private void Meld() { if (heapForestHead == null) { maxNode = null; return; } //degree - node dictionary var mergeDictionary = new Dictionary <int, FibornacciHeapNode <T> >(); var current = heapForestHead; maxNode = current; while (current != null) { current.Parent = null; var next = current.Next; //no same degree already in merge dictionary //add to hash table if (!mergeDictionary.ContainsKey(current.Degree)) { mergeDictionary.Add(current.Degree, current); if (maxNode == current) { maxNode = null; } DeleteNode(ref heapForestHead, current); current = next; continue; } //insert back to forest by merging current tree //with existing tree in merge dictionary else { var currentDegree = current.Degree; var existing = mergeDictionary[currentDegree]; if (existing.Value.CompareTo(current.Value) > 0) { current.Parent = existing; DeleteNode(ref heapForestHead, current); var childHead = existing.ChildrenHead; InsertNode(ref childHead, current); existing.ChildrenHead = childHead; existing.Degree++; InsertNode(ref heapForestHead, existing); current = existing; current.Next = next; } else { existing.Parent = current; var childHead = current.ChildrenHead; InsertNode(ref childHead, existing); current.ChildrenHead = childHead; current.Degree++; } if (maxNode == null || maxNode.Value.CompareTo(current.Value) < 0) { maxNode = current; } mergeDictionary.Remove(currentDegree); } } //insert back trees with unique degrees to forest if (mergeDictionary.Count > 0) { foreach (var node in mergeDictionary) { InsertNode(ref heapForestHead, node.Value); if (maxNode == null || maxNode.Value.CompareTo(node.Value.Value) < 0) { maxNode = node.Value; } } mergeDictionary.Clear(); } }
private void Meld() { if (heapForestHead == null) { minNode = null; return; } var mergeDictionary = new Dictionary <int, FibornacciHeapNode <T> >(); var current = heapForestHead; minNode = current; while (current != null) { current.Parent = null; var next = current.Next; if (!mergeDictionary.ContainsKey(current.Degree)) { mergeDictionary.Add(current.Degree, current); if (minNode == current) { minNode = null; } DeleteNode(ref heapForestHead, current); current = next; continue; } else { var currentDegree = current.Degree; var existing = mergeDictionary[currentDegree]; if (existing.Value.CompareTo(current.Value) < 0) { current.Parent = existing; DeleteNode(ref heapForestHead, current); var childHead = existing.ChildrenHead; InsertNode(ref childHead, current); existing.ChildrenHead = childHead; existing.Degree++; InsertNode(ref heapForestHead, existing); current = existing; current.Next = next; } else { existing.Parent = current; var childHead = current.ChildrenHead; InsertNode(ref childHead, existing); current.ChildrenHead = childHead; current.Degree++; } if (minNode == null || minNode.Value.CompareTo(current.Value) > 0) { minNode = current; } mergeDictionary.Remove(currentDegree); } } if (mergeDictionary.Count > 0) { foreach (var node in mergeDictionary) { InsertNode(ref heapForestHead, node.Value); if (minNode == null || minNode.Value.CompareTo(node.Value.Value) > 0) { minNode = node.Value; } } mergeDictionary.Clear(); } }