/// <summary> /// Inserts an element into the heap. /// </summary> /// <param name="item">The element to insert into the heap.</param> /// <returns>The pointer to the inserted element.</returns> public ElementPointer Insert(T item) { var result = new OptimizedChildSiblingTreeNode <T>(item); this._head = this._head == null ? result : this.Meld(result, this._head); return(new(result)); }
/// <summary> /// Destructively merges another heap. /// </summary> /// <param name="heap">Another heap with elements to add to this heap.</param> /// <remarks><paramref name="heap"/> is emptied in the process.</remarks> public void Merge(PairingHeap <T> heap) { if (heap._head == null) { return; } this._head = this._head == null ? heap._head : this.Meld(heap._head, this._head); heap._head = null; }
private OptimizedChildSiblingTreeNode <T> Meld(OptimizedChildSiblingTreeNode <T> head1, OptimizedChildSiblingTreeNode <T> head2) { if (this._comparer.Compare(head1.Value, head2.Value) < 0) { MeldInto(head1, head2); return(head1); } else { MeldInto(head2, head1); return(head2); }
/// <summary> /// Extracts a minimum element from the heap. /// </summary> /// <param name="result">A minimum element that was contained in the heap.</param> /// <returns><c>true</c> if an element was removed from the heap; otherwise, <c>false</c>.</returns> public bool TryExtractMinimum([MaybeNullWhen(false)] out T result) { if (this._head == null) { result = default; return(false); } result = this._head.Value; this._head = this.MergePairs(this._head.FirstChild); return(true); }
private OptimizedChildSiblingTreeNode <T>?MergePairs(OptimizedChildSiblingTreeNode <T>?firstChild) { if (firstChild == null) { return(null); } var last = PassOne(firstChild); var result = PassTwo(last); result.LeftSiblingOrParent = null; result.RightSibling = null; return(result); OptimizedChildSiblingTreeNode <T> PassOne(OptimizedChildSiblingTreeNode <T> current) { OptimizedChildSiblingTreeNode <T>?previous = null; while (current.RightSibling != null) { var other = current.RightSibling; var next = other.RightSibling; var melded = this.Meld(current, other); melded.LeftSiblingOrParent = previous; if (next == null) { return(melded); } previous = melded; current = next; } current.LeftSiblingOrParent = previous; return(current); } OptimizedChildSiblingTreeNode <T> PassTwo(OptimizedChildSiblingTreeNode <T> current) { var merging = current.LeftSiblingOrParent; while (merging != null) { var next = merging.LeftSiblingOrParent; current = this.Meld(current, merging); merging = next; } return(current); } }
static void MeldInto(OptimizedChildSiblingTreeNode <T> parent, OptimizedChildSiblingTreeNode <T> child) { child.LeftSiblingOrParent = parent; var oldFirstChild = parent.FirstChild; if (oldFirstChild != null) { oldFirstChild.LeftSiblingOrParent = child; } child.RightSibling = oldFirstChild; parent.FirstChild = child; }
private static void Cut(OptimizedChildSiblingTreeNode <T> node) { var reference = node.LeftSiblingOrParent !; if (reference.FirstChild == node) { reference.FirstChild = node.RightSibling; } else { Debug.Assert(reference.RightSibling == node); reference.RightSibling = node.RightSibling; } }
/// <summary> /// Decreases the element inside a specified element pointer. /// </summary> /// <param name="element">The pointer to the element to decrease.</param> /// <param name="item">The new element.</param> /// <remarks>It is undefined behavior to increase the element.</remarks> public void Decrease(ElementPointer element, T item) { Debug.Assert(this._head != null); var node = element.Node; if (this._head == node) { node.Value = item; return; } Cut(node); node.LeftSiblingOrParent = null; node.RightSibling = null; node.Value = item; this._head = this.Meld(this._head !, node); }
/// <summary> /// Removes an element from the heap. /// </summary> /// <param name="element">The pointer to the element to be removed.</param> public void Remove(ElementPointer element) { Debug.Assert(this._head != null); var node = element.Node; if (this._head == node) { this._head = this.MergePairs(this._head.FirstChild); return; } Cut(node); if (node.FirstChild != null) { this._head = this.Meld(this._head !, this.MergePairs(node.FirstChild)); } }
internal ElementPointer(OptimizedChildSiblingTreeNode <T> node) { this._node = node; }