public void testChangePriority() {
    PriorityQueue q = new MinHeap(N);
    Item items[] = new Item[N];
    for (int i = 0; i < N; i++) {
      Item e = new Item(N - i - 1);
      q.insert(e);
      items[i] = e;
    }

    q.changePriority(items[N - 1], -2);
    q.changePriority(items[N / 2], -1);
    q.changePriority(items[N / 2 + 1], N * 2);

    int j = 0;
    double pr_last = Double.NEGATIVE_INFINITY;
    assertTrue("descending size", q.size() == N);

    while (q.size() > 0) {
      assertTrue("descending extract", j < N);
      QueueElement e = q.extractMin();
      assertTrue("descending order", e.getPriority() > pr_last);
      pr_last = e.getPriority();
      if (j == 0) assertTrue("lowest elt", e.getPriority() == -2);
      if (j == 1) assertTrue("second-lowest elt", e.getPriority() == -1);
      if (q.size() == 1) assertTrue("penultimate elt", e.getPriority() == N - 1);
      if (q.size() == 0) assertTrue("final elt", e.getPriority() == N * 2);
      j++;
    }
  }
  public void testReverse() {
    PriorityQueue q = new MinHeap(N);
    Item items[] = new Item[N];
    for (int i = 0; i < N; i++) {
      Item e = new Item(N - i - 1);
      q.insert(e);
      items[i] = e;
    }

    for (int i = 0; i < N; i++) {
      q.changePriority(items[i], i);
    }

    int j = 0;
    double pr_last = Double.NEGATIVE_INFINITY;
    assertTrue("ascending size", q.size() == N);

    while (q.size() > 0) {
      assertTrue("ascending extract", j < N);
      QueueElement e = q.extractMin();
      assertTrue("ascending order", e.getPriority() > pr_last);
      pr_last = e.getPriority();
      assertEquals("ascending priority", items[j].getPriority(), e.getPriority());
      assertEquals("ascending identity", items[j], e);
      j++;
    }
  }
  public void testEqualKeys() {
    PriorityQueue q = new MinHeap(N);
    Item[] items = new Item[20];
    int j = 0;

    for (int i = 0; i < 5; i++) {
      items[j] = new Item(5);
      q.insert(items[j]);
      j++;
    }
    for (int i = 0; i < 5; i++) {
      items[j] = new Item(3);
      q.insert(items[j]);
      j++;
    }
    for (int i = 0; i < 5; i++) {
      items[j] = new Item(4);
      q.insert(items[j]);
      j++;
    }
    for (int i = 0; i < 5; i++) {
      items[j] = new Item(7);
      q.insert(items[j]);
      j++;
    }

    assertEquals(20, q.size());
    for (int i = 0; i < items.length; i++) {
      assertTrue(q.contains(items[i]));
    }

    for (int i = 0; i < 5; i++) {
      QueueElement e = q.extractMin();
      assertTrue(q.contains(q.min()));
      assertEquals(3.0, e.getPriority());
    }
    for (int i = 0; i < 5; i++) {
      QueueElement e = q.extractMin();
      assertTrue(q.contains(q.min()));
      assertEquals(4.0, e.getPriority());
    }
    for (int i = 0; i < 5; i++) {
      QueueElement e = q.extractMin();
      assertTrue(q.contains(q.min()));
      assertEquals(5.0, e.getPriority());
    }
    for (int i = 0; i < 5; i++) {
      QueueElement e = q.extractMin();
      if (q.size() > 0) assertTrue(q.contains(q.min()));
      assertEquals(7.0, e.getPriority());
    }
  }
 public void testDescending() {
   PriorityQueue q = new MinHeap(N);
   double p[] = new double[N];
   for (int i = 0; i < N; i++) {
     p[i] = i;
     Item e = new Item(N - i - 1);
     q.insert(e);
   }
   int j = 0;
   double pr = Double.NEGATIVE_INFINITY;
   assertTrue("descending size", q.size() == N);
   while (q.size() > 0) {
     assertTrue("descending extract", j < N);
     QueueElement e = q.extractMin();
     assertTrue("descending order", e.getPriority() > pr);
     assertEquals("descending priority", e.getPriority(), p[j++], 1e-5);
     pr = e.getPriority();
   }
 }