예제 #1
0
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;
        }
    }
}
예제 #2
0
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);
            }
        }
    }
}
예제 #3
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);
    }
}