void pqueue_heapify(pqueue_t *queue, size_t idx) { /* left index, right index, largest */ void *tmp = NULL; size_t l_idx, r_idx, lrg_idx; if (queue == NULL) return; l_idx = LEFT(idx); r_idx = RIGHT(idx); /* left child exists, compare left child with its parent */ if (l_idx < queue->size && queue->cmp(queue->data[l_idx], queue->data[idx]) > 0) { lrg_idx = l_idx; } else { lrg_idx = idx; } /* right child exists, compare right child with the largest element */ if (r_idx < queue->size && queue->cmp(queue->data[r_idx], queue->data[lrg_idx]) > 0) { lrg_idx = r_idx; } /* at this point largest element was determined */ if (lrg_idx != idx) { /* swap between the index at the largest element */ tmp = queue->data[lrg_idx]; queue->data[lrg_idx] = queue->data[idx]; queue->data[idx] = tmp; /* heapify again */ pqueue_heapify(queue, lrg_idx); } }
/** * * Turn an "almost-heap" into a heap . * */ void pqueue_heapify(PQueue *q, size_t idx) { /* left index, right index, largest */ void *tmp = NULL; size_t l_idx, r_idx, lrg_idx; NP_CHECK(q); l_idx = LEFT(idx); r_idx = RIGHT(idx); /* Left child exists, compare left child with its parent */ if (l_idx < q->size && q->cmp(q->data[l_idx], q->data[idx]) < 0) { lrg_idx = l_idx; } else { lrg_idx = idx; } /* Right child exists, compare right child with the largest element */ if (r_idx < q->size && q->cmp(q->data[r_idx], q->data[lrg_idx]) < 0) { lrg_idx = r_idx; } /* At this point largest element was determined */ if (lrg_idx != idx) { /* Swap between the index at the largest element */ tmp = q->data[lrg_idx]; q->data[lrg_idx] = q->data[idx]; q->data[idx] = tmp; /* Heapify again */ pqueue_heapify(q, lrg_idx); } }
void pqueue_replace_data(pqueue_t *queue, void *old_data, void *new_data, queue_cmp cmp, queue_swp swp) { size_t i; for(i=0; i<queue->size; ++i) { if ((*cmp)(queue->data[i], old_data)) { (*swp)(&queue->data[i], &new_data); pqueue_heapify(queue, 0); break; } } }
void* pqueue_dequeue(pqueue_t *queue) { void *data = NULL; if (queue == NULL || queue->size < 1) return NULL; data = queue->data[0]; queue->data[0] = queue->data[queue->size-1]; queue->size--; /* restore heap property */ pqueue_heapify(queue, 0); return (data); }
/** * * Returns the element with the biggest priority from the queue . * */ void *pqueue_dequeue(PQueue *q) { void *data = NULL; NP_CHECK(q); if (q->size < 1) { /* Priority Queue is empty */ //DEBUG("Priority Queue underflow . Cannot remove another element ."); return NULL; } data = q->data[0]; q->data[0] = q->data[q->size-1]; q->size--; /* Restore heap property */ pqueue_heapify(q, 0); return (data); }