void link(HeapNode y, HeapNode x) {
   // moves y to a child position of x
   rootList.remove(y);
   x.addChild(y);
   y.setParent(x);
   y.setMark(false);
 }
  /**
   * removes child node from tree and starts a new one with it.
   *
   * @param x
   * @param y
   */
  protected void cut(HeapNode x, HeapNode y) {
    // remove x from child list of y and decrement y.degree
    y.removeChild(x);

    // add x to root list
    rootList.insert(x);
    x.setParent(null);
    x.setMark(false);
  }
 /**
  * c*O(1)
  *
  * @param y
  */
 protected void cascadingCut(HeapNode y) {
   HeapNode z = y.getParent();
   if (z != null) {
     if (!y.isMark()) {
       y.setMark(true);
     } else {
       cut(y, z);
       cascadingCut(z);
     }
   }
 }
  /**
   * insert node into heap. runtime is O(1). makes no attempt to consolidate tree.
   *
   * @param node
   */
  public void insert(HeapNode node) {
    if (node.getKey() == DoubleLinkedCircularList.noValue) {
      throw new IllegalArgumentException("node.key must be set before insert into heap");
    }
    node.setNumberOfChildren(0);
    node.setParent(null);
    node.removeChildren();
    node.setLeft(node);
    node.setRight(node);
    node.setMark(false);

    // concatenate root list containing node with this.rootList
    rootList.insert(node);

    if ((minimumNode == null) || (node.getKey() < minimumNode.getKey())) {
      minimumNode = node;
    }

    n++;
  }