bool test_random(int numItems) {
  MinBinaryHeap h;
  Container ** nodePointers = new Container * [numItems];
  IntegerData ** values = new IntegerData * [numItems];
  bool failed = false;
  int i;

  for (i = 0; i < numItems; i++) {
    // need to be careful not to work with data that is near integer max or min value
    values[i] = new IntegerData(rand() % numItems);
    nodePointers[i] = h.insert(values[i]);
  }

  failed = false;
  for (i = 0; i < numItems; i++) {
    // need to be careful not to work with data that is near integer max or min value
    // because if we subtract from min or add to max we get overflow (undefined behavior)
    if (i % 2 == 0) {
      values[i]->value -= rand() % numItems;
      h.decreaseKey(nodePointers[i]);
    }
    else {
      values[i]->value += rand() % numItems;
      h.increaseKey(nodePointers[i]);
    }
  }
  IntegerData * x = (IntegerData*)h.deleteMin();
  int lastValue = x->value;
  delete x;
  for(i = 1; i < numItems; i++ ) {
    x = (IntegerData*)h.deleteMin();

    if( x->value < lastValue ) {
      cout << "Oops! " << x->value << " is not >= " << lastValue << endl;
      failed = true;
    }
    lastValue = x->value;

    delete x;
  }
  if (failed) {
    cout << "random test failed" << endl;
  }
  else {
    cout << "random test successful" << endl;
  }

  delete [] nodePointers;
  delete [] values;

  return failed;
}
bool test_increase_decreaseKey(int numItems) {
  MinBinaryHeap h;
  Container ** nodePointers = new Container * [numItems];
  IntegerData ** values = new IntegerData * [numItems];
  bool failed = false;
  int i;

  for (i = 0; i < numItems; i++) {
    values[i] = new IntegerData(i);
    nodePointers[i] = h.insert(values[i]);
  }

  failed = false;
  for (i = 0; i < numItems; i++) {
    // decrease all the even ones by 1, increase all the odd ones by 9998
    // should result in the sequence -1, 1, 3, ..., 9995, 9997, (odds + 9998)=9999, 10001...
    if (i % 2 == 0) {
      values[i]->value--;
      h.decreaseKey(nodePointers[i]);
    }
    else {
      values[i]->value+=9998;
      h.increaseKey(nodePointers[i]);
    }
  }

  for(i = 0; i < numItems; i++ ) {
    IntegerData * x = (IntegerData*)h.deleteMin();

    if( x->value != (i*2-1) ) {
      cout << "Oops! " << (i*2-1) << " != " << x->value << endl;
      failed = true;
    }
    delete x;
  }
  if (failed) {
    cout << "decreaseKey evens/increaseKey odds 0:9999 failed" << endl;
  }
  else {
    cout << "decreaseKey evens/increaseKey odds 0:9999 successful" << endl;
  }

  delete [] nodePointers;
  delete [] values;

  return failed;
}