/** * extract minimum from the heap. * * <p>minor differences from Cormen et al. pseudocode are present. * * @return */ public HeapNode extractMin() { int sentinel = DoubleLinkedCircularList.sentinelKey; HeapNode z = minimumNode; if (z != null) { // detach each child and add it to heap HeapNode x = z.getChildren().getSentinel().getRight(); // for each child x of z while (x.getKey() != sentinel) { HeapNode next = x.getRight(); rootList.insert(x); x = next; } rootList.remove(z); if (z.getRight().getKey() == z.getKey()) { minimumNode = null; } else { minimumNode = z.getRight(); consolidate(); } n--; } return z; }
/** * a depth first search of all nodes (that is, it descends all children of a node before * proceeding to the next in the current doubly linked circular list). * * @param key * @return */ HeapNode search(long key) { HeapNode node = rootList.getSentinel().getRight(); int sentinel = DoubleLinkedCircularList.sentinelKey; Stack<HeapNode> stack = new Stack<HeapNode>(); while (!stack.isEmpty() || (node.getKey() != sentinel)) { if (node.getKey() != sentinel) { stack.push(node); node = node.getRight(); } else { node = stack.pop(); // System.out.println(node.key); if (node.getKey() == key) { return node; } node = node.getChildren().getSentinel().getRight(); } } return null; }
protected void printRootList() { StringBuffer sb = new StringBuffer(); HeapNode t = this.rootList.getSentinel().getRight(); while (t.getKey() != DoubleLinkedCircularList.sentinelKey) { if ((minimumNode == null) || (t.getKey() < minimumNode.getKey())) { minimumNode = t; } String str = String.format("%d", t.getKey()); if (sb.length() > 0) { sb.append(" "); } sb.append(str); t = t.getRight(); } sb.insert(0, "Looking for " + minimumNode + " :"); log.info(sb.toString()); }
@Override public void runAlgorithm() throws InterruptedException { final HeapNode v = new HeapNode(H, K, ZDepth.ACTIONNODE); addToScene(v); setHeader("insertion"); if (H.getN() == 1000) { addStep("heapfull"); removeFromScene(v); return; } HeapNode w; // link H.setN(H.getN() + 1); final int n = H.getN(); int k = 1 << 10; if (n == 1) { H.setRoot(w = v); v.goToRoot(); pause(); } else { while ((k & n) == 0) { k >>= 1; } k >>= 1; w = H.getRoot(); while (k > 1) { w = ((n & k) == 0) ? w.getLeft() : w.getRight(); k >>= 1; } if ((k & n) == 0) { w.linkLeft(v); } else { w.linkRight(v); } v.mark(); H.reposition(); pause(); } removeFromScene(v); v.unmark(); // pause(); bubbleup(v); }
void consolidate() { // D[n] = max degree of any node = lg_2(n) = lg_2(Integer.MAX) = 31 // int maxDegree = (int) (Math.log(this.n)/Math.log(2)); int maxDegree = 31; HeapNode[] a = new HeapNode[maxDegree]; HeapNode w = rootList.getSentinel().getRight(); // n*m*(constants) while (w.getKey() != DoubleLinkedCircularList.sentinelKey) { HeapNode x = w; // because the x.right gets changed in link(), nab the next // reference before link HeapNode next = w.getRight(); int d = x.getNumberOfChildren(); // is there another node of the same degree, that is, has the // same number of children? while ((d < a.length) && (a[d] != null)) { HeapNode y = a[d]; if (x.getKey() > y.getKey()) { HeapNode tmp = x; x = y; y = tmp; } // link removes y (which has a key larger than x now) from // rootList and adds it as a child of x link(y, x); a[d] = null; d++; } if (d < a.length) { a[d] = x; } else { throw new IllegalStateException("maxDegree=" + maxDegree + " but d is " + d); } w = next; } minimumNode = null; for (int i = 0; i < a.length; i++) { if (a[i] != null) { rootList.remove(a[i]); rootList.insert(a[i]); // not changing the minimumNode because the rootList content // has not changed, so the minimum in that has not changed if ((minimumNode == null) || (a[i].getKey() < minimumNode.getKey())) { minimumNode = a[i]; } } } }