void pq_delete_min(PQ pq, void *retval) { int floater; /* previous loser floating down */ int small_child; /* smaller child of floater */ assert(!pq_is_empty(pq)); /* first copy out the winner */ memcpy(retval, REF(pq, 0), pq->element_length); --(pq->n); if(pq_is_empty(pq)) { /* pq empty, nothing to do */ return; } /* else */ memcpy(REF(pq, 0), REF(pq, pq->n), pq->element_length); floater = 0; for(;;) { /* find smaller child of floater */ if(Child(floater, 0) >= pq->n) { return; /* no children, bail out */ } else if(Child(floater, 1) >= pq->n) { small_child = Child(floater, 0); } else if(pq->compare(REF(pq, Child(floater, 0)), REF(pq, Child(floater, 1))) < 0) { small_child = Child(floater, 0); } else { small_child = Child(floater, 1); } /* is floater <= small_child? */ if(pq->compare(REF(pq, floater), REF(pq, small_child)) <= 0) { /* yes, we are done */ return; } else { /* no, swap and continue floating down */ pq_swap(pq, floater, small_child); floater = small_child; } } }
void pq_sanity_check(PQ pq) { int i; int j; assert(pq->n >= 0); assert(pq->n <= pq->size); for(i = 0; i < pq->n; i++) { for(j = 0; j < NUM_CHILDREN; j++) { if(Child(i, j) < pq->n) { assert(pq->compare(REF(pq, i), REF(pq, Child(i, j))) <= 0); } } } }
void pq_insert(PQ pq, const void *elt) { int floater; /* new element */ while(pq->n + 1 > pq->size) { pq->size *= 2; pq->data = realloc(pq->data, pq->element_length * pq->size); assert(pq->data); } /* copy the new element in */ floater = pq->n++; memcpy(REF(pq, floater), elt, pq->element_length); /* float it up until it is at the top */ /* or it is no smaller than its parent */ while(floater > 0 && pq->compare(REF(pq, floater), REF(pq, Parent(floater))) <= 0) { /* it's smaller than its parent */ pq_swap(pq, floater, Parent(floater)); floater = Parent(floater); } }