void moveDown(int i, boolean min) {
    int size = heap.size();
    while (i < size) {
      int p = highDescendant(i, min);
      if (p < 0) {
        return;
      }
      int cmp = compare(heap.get(p), heap.get(i));
      if (i == grandParent(p)) {
        if (min ? cmp < 0 : cmp > 0) {
          swap(i, p);
          int pr = parent(p);
          int c = compare(heap.get(p), heap.get(pr));
          if (min ? c > 0 : c < 0) {
            swap(p, pr);
          }
        }
      } else {
        if (min ? cmp < 0 : cmp > 0) {
          swap(i, p);
          return;
        }
      }
      i = p;
    }
  }