/// <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> Insert into the priority queue, maintaining heap order. /// This implementation is not optimized for O(1) performance. /// </summary> /// <param name="x">the item to insert. /// </param> /// <exception cref="Overflow">if capacity exceeded. /// </exception> public virtual void insert(Comparable x) { BinomialQueue oneItem = new BinomialQueue(); oneItem.currentSize = 1; oneItem.theTrees[0] = new BinomialNode(x); merge(oneItem); }
public static void Main(System.String[] args) { int numItems = 10000; BinomialQueue h = new BinomialQueue(); BinomialQueue h1 = new BinomialQueue(); int i = 37; System.Console.Out.WriteLine("Starting check."); try { for (i = 37; i != 0; i = (i + 37) % numItems) { if (i % 2 == 0) { h1.insert(new MyInteger(i)); } else { h.insert(new MyInteger(i)); } } h.merge(h1); for (i = 1; i < numItems; i++) { if (((MyInteger)(h.deleteMin())).intValue() != i) { System.Console.Out.WriteLine("Oops! " + i); } } } catch (Overflow e) { System.Console.Out.WriteLine("Unexpected overflow"); } System.Console.Out.WriteLine("Check done."); }
/// <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; }