/**
   * 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;
  }