private void RemoveTreeRoot(Node <T> root, Node <T> prev) { if (root == _head) { _head = root.Sibling; } else { prev.Sibling = root.Sibling; } Node <T> newHead = null; var child = root.Child; while (child != null) { var next = child.Sibling; child.Sibling = newHead; child.Parent = null; newHead = child; child = next; } var newHeap = new BinomialHeap <T>(newHead, _comparer); _head = Union(newHeap); }
private Node <T> Union(BinomialHeap <T> heap) { var newHead = Union(this, heap); _head = null; heap._head = null; if (newHead == null) { return(null); } Node <T> prev = null; var curr = newHead; var next = newHead.Sibling; while (next != null) { if (curr.Degree != next.Degree || (next.Sibling != null && next.Sibling.Degree == curr.Degree)) { prev = curr; curr = next; } else { if (Compare(curr, next) < 0) { curr.Sibling = next.Sibling; LinkTree(curr, next); } else { if (prev == null) { newHead = next; } else { prev.Sibling = next; } LinkTree(next, curr); curr = next; } } next = curr.Sibling; } return(newHead); }
private static Node <T> Union(BinomialHeap <T> heap1, BinomialHeap <T> heap2) { if (heap1._head == null) { return(heap2._head); } if (heap2._head == null) { return(heap1._head); } Node <T> head; var heap1Next = heap1._head; var heap2Next = heap2._head; if (heap1._head.Degree <= heap2._head.Degree) { head = heap1._head; heap1Next = heap1Next.Sibling; } else { head = heap2._head; heap2Next = heap2Next.Sibling; } var tail = head; while (heap1Next != null && heap2Next != null) { if (heap1Next.Degree <= heap2Next.Degree) { tail.Sibling = heap1Next; heap1Next = heap1Next.Sibling; } else { tail.Sibling = heap2Next; heap2Next = heap2Next.Sibling; } tail = tail.Sibling; } tail.Sibling = heap1Next ?? heap2Next; return(head); }
/// <summary> /// Combine the heap with another to form a valid binomial heap. /// </summary> /// <param name="heap">Another binomial heap.</param> public void Merge(BinomialHeap <T> heap) { _head = Union(heap); }