private void deleteNode(ref FibonacciHeapNode <T> heapForestHead, FibonacciHeapNode <T> deletionNode) { if (deletionNode == heapForestHead) { if (deletionNode.Next != null) { deletionNode.Next.Previous = null; } heapForestHead = deletionNode.Next; deletionNode.Next = null; deletionNode.Previous = null; return; } deletionNode.Previous.Next = deletionNode.Next; if (deletionNode.Next != null) { deletionNode.Next.Previous = deletionNode.Previous; } deletionNode.Next = null; deletionNode.Previous = null; }
/// <summary> /// Delete this node from Heap Tree and adds it to forest as a new tree /// </summary> private void cut(FibonacciHeapNode <T> node) { var parent = node.Parent; //cut child and attach to heap Forest //and mark parent for lost child var childHead = node.Parent.ChildrenHead; deleteNode(ref childHead, node); node.Parent.ChildrenHead = childHead; node.Parent.Degree--; if (parent.Parent != null) { parent.LostChild = true; } node.LostChild = false; node.Parent = null; insertNode(ref heapForestHead, node); //update if (comparer.Compare(minMaxNode.Value, node.Value) > 0) { minMaxNode = node; } }
private void removeMapping(T currentValue, FibonacciHeapNode <T> node) { heapMapping[currentValue].Remove(node); if (heapMapping[currentValue].Count == 0) { heapMapping.Remove(currentValue); } }
private void addMapping(T newItem, FibonacciHeapNode <T> newNode) { if (heapMapping.ContainsKey(newItem)) { heapMapping[newItem].Add(newNode); } else { heapMapping[newItem] = new List <FibonacciHeapNode <T> >(new[] { newNode }); } }
/// <summary> /// Merges the given fibornacci node list to current Forest /// </summary> private void mergeForests(FibonacciHeapNode <T> headPointer) { var current = headPointer; while (current != null) { var next = current.Next; insertNode(ref heapForestHead, current); current = next; } }
/// <summary> /// Update the Heap with new value for this node pointer. /// Time complexity: O(1). /// </summary> public void UpdateKey(T currentValue, T newValue) { var node = heapMapping[currentValue]?.Where(x => x.Value.Equals(currentValue)).FirstOrDefault(); if (node == null) { throw new Exception("Current value is not present in this heap."); } if (comparer.Compare(newValue, node.Value) > 0) { throw new Exception($"New value is not {(!isMaxHeap ? "less" : "greater")} than old value."); } updateNodeValue(currentValue, newValue, node); if (node.Parent == null && comparer.Compare(minMaxNode.Value, node.Value) > 0) { minMaxNode = node; } var current = node; if (current.Parent == null || comparer.Compare(current.Value, current.Parent.Value) >= 0) { return; } 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) { return; } cut(parent); cut(current); } else { cut(current); } }
private void insertNode(ref FibonacciHeapNode <T> head, FibonacciHeapNode <T> newNode) { newNode.Next = newNode.Previous = null; if (head == null) { head = newNode; return; } head.Previous = newNode; newNode.Next = head; head = newNode; }
/// <summary> /// Time complexity: O(1). /// </summary> public void Insert(T newItem) { var newNode = new FibonacciHeapNode <T>(newItem); //return pointer to new Node mergeForests(newNode); if (minMaxNode == null) { minMaxNode = newNode; } else { if (comparer.Compare(minMaxNode.Value, newNode.Value) > 0) { minMaxNode = newNode; } } addMapping(newItem, newNode); Count++; }
private void updateNodeValue(T currentValue, T newValue, FibonacciHeapNode <T> node) { removeMapping(currentValue, node); node.Value = newValue; addMapping(newValue, node); }
/// <summary> /// Merge roots with same degrees in Forest. /// </summary> private void meld() { if (heapForestHead == null) { minMaxNode = null; return; } //degree - node dictionary var mergeDictionary = new Dictionary <int, FibonacciHeapNode <T> >(); var current = heapForestHead; minMaxNode = 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 (minMaxNode == current) { minMaxNode = null; } deleteNode(ref heapForestHead, current); current = next; } //insert back to forest by merging current tree //with existing tree in merge dictionary else { var currentDegree = current.Degree; var existing = mergeDictionary[currentDegree]; if (comparer.Compare(existing.Value, 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 (minMaxNode == null || comparer.Compare(minMaxNode.Value, current.Value) > 0) { minMaxNode = 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 (minMaxNode == null || comparer.Compare(minMaxNode.Value, node.Value.Value) > 0) { minMaxNode = node.Value; } } mergeDictionary.Clear(); } }