private Node <T> Merge(BinomialHeap <T> otherHeap) { Contract.Requires <ArgumentNullException>(otherHeap != null); //for traversing first heap Node <T> current1; //for traversing second heap Node <T> current2; //Make root the smaller root if (root.Value.CompareTo(otherHeap.root.Value) <= 0) { current1 = otherHeap.root; current2 = root.RightSibling; } else { current2 = root; root = otherHeap.root; current1 = otherHeap.root.RightSibling; } //pointer for currently building merged heap Node <T> current = root; while (current1 != null && current2 != null) { //merge phase like merge sort, insert smaller element first if (current1.Value.CompareTo(current2.Value) < 0) { current.RightSibling = current1; current1 = current1.RightSibling; current = current.RightSibling; } else { current.RightSibling = current2; current2 = current2.RightSibling; current = current.RightSibling; } } Node <T> tail; //check which heap is not fully visited if (current1 == null) { tail = current2; } else { tail = current1; } //insert remaining elements of other heap while (tail != null) { current.RightSibling = tail; current = current.RightSibling; tail = tail.RightSibling; } return(root); }
public BinomialHeap <T> Unify(BinomialHeap <T> heap) { Contract.Requires <ArgumentNullException>(heap != null); Node <T> root = Merge(heap); if (root == null) { return(null); } //restore the property no two sub tree has same order Node <T> prev = null; var current = root; var next = current.RightSibling; while (next != null) { //orders are not same, don't need merging var needMerge = current.Degree == next.Degree; if (next.RightSibling != null && next.RightSibling.Degree == next.Degree) { //orders are not same, don't need merging needMerge = false; } if (needMerge) { if (current.Value.CompareTo(next.Value) <= 0) { //current node is smaller than next node //link the next to next node and skip next node //make next node child of current node current.RightSibling = next.RightSibling; Link(current, next); } else if (prev != null) { //current node is greater than next node //link to next node skipping current node and //make it child of next node prev.RightSibling = next; Link(next, current); } else { //previous is null means this is root node //make current node child of next node //and next node is the new root root = next; Link(next, current); } } else { prev = current; current = next; } next = current.RightSibling; } return(new BinomialHeap <T>(root)); }
public void Insert(T element) { //first make 0 order binomial heap //then merge it with current heap BinomialHeap <T> heap = CreateBinomialHeap(element); heap.root.Degree = 1; Unify(heap); }
public static T ExtractMin(BinomialHeap <T> heap) { Contract.Requires <ArgumentNullException>(heap != null, "heap"); T min = heap.GetMin(); //List of children to root node, because it's getting removed List <Node <T> > rootList = new List <Node <T> >(); Node <T> current = heap.root.RightSibling; while (current != null) { //Assign parent field of children to null current.Parent = null; rootList.Add(current); } BinomialHeap <T> newHeap = CreateBinomialHeap(); newHeap.root = rootList[0]; heap = heap.Unify(newHeap); return(min); }