/// <summary> Remove the smallest item from the priority queue.</summary> /// <returns> the smallest item, or null, if empty. /// </returns> public virtual Comparable deleteMin() { if (Empty) { return(null); } int minIndex = findMinIndex(); Comparable minItem = theTrees[minIndex].element; BinomialNode deletedTree = theTrees[minIndex].leftChild; BinomialQueue deletedQueue = new BinomialQueue(); deletedQueue.currentSize = (1 << minIndex) - 1; for (int j = minIndex - 1; j >= 0; j--) { deletedQueue.theTrees[j] = deletedTree; deletedTree = deletedTree.nextSibling; deletedQueue.theTrees[j].nextSibling = null; } theTrees[minIndex] = null; currentSize -= (deletedQueue.currentSize + 1); try { merge(deletedQueue); } catch (Overflow e) { } return(minItem); }
/// <summary> Return the result of merging equal-sized t1 and t2.</summary> private static BinomialNode combineTrees(BinomialNode t1, BinomialNode t2) { if (t1.element.compareTo(t2.element) > 0) { return(combineTrees(t2, t1)); } t2.nextSibling = t1.leftChild; t1.leftChild = t2; return(t1); }
/// <summary> Merge rhs into the priority queue. /// rhs becomes empty. rhs must be different from this. /// </summary> /// <param name="rhs">the other binomial queue. /// </param> /// <exception cref="Overflow">if result exceeds capacity. /// </exception> public virtual void merge(BinomialQueue rhs) { if (this == rhs) { // Avoid aliasing problems return; } if (currentSize + rhs.currentSize > capacity()) { throw new Overflow(); } currentSize += rhs.currentSize; BinomialNode carry = null; for (int i = 0, j = 1; j <= currentSize; i++, j *= 2) { BinomialNode t1 = theTrees[i]; BinomialNode t2 = rhs.theTrees[i]; int whichCase = t1 == null?0:1; whichCase += (t2 == null?0:2); whichCase += (carry == null?0:4); switch (whichCase) { case 0: /* No trees */ case 1: /* Only this */ break; case 2: /* Only rhs */ theTrees[i] = t2; rhs.theTrees[i] = null; break; case 4: /* Only carry */ theTrees[i] = carry; carry = null; break; case 3: /* this and rhs */ carry = combineTrees(t1, t2); theTrees[i] = rhs.theTrees[i] = null; break; case 5: /* this and carry */ carry = combineTrees(t1, carry); theTrees[i] = null; break; case 6: /* rhs and carry */ carry = combineTrees(t2, carry); rhs.theTrees[i] = null; break; case 7: /* All three */ theTrees[i] = carry; carry = combineTrees(t1, t2); rhs.theTrees[i] = null; break; } } for (int k = 0; k < rhs.theTrees.Length; k++) { rhs.theTrees[k] = null; } rhs.currentSize = 0; }
/// <summary> Construct the binomial queue.</summary> public BinomialQueue() { theTrees = new BinomialNode[MAX_TREES]; makeEmpty(); }
internal BinomialNode(Comparable theElement, BinomialNode lt, BinomialNode nt) { element = theElement; leftChild = lt; nextSibling = nt; }