/** * @brief CSLR MAX-HEAPIFY * * This routine creates a max-heap for the subtree rooted at index i. The * index is 0 based. * * @param[in] h The heap to operate on * @param[in] i The (0-based) subtree index * @return HEAP_ERR_E */ HEAP_ERR_E heap_max_heapify (HEAP_T* h, unsigned long i) { unsigned long l = HEAP_LEFT(i); unsigned long r = HEAP_RIGHT(i); unsigned long largest; //fprintf (stdout, "i=%lu; l=%lu; r=%lu\n", i, l, r); if (h->type == DS_HEAP_MIN) return HEAP_ERR_WRONG_TYPE; if (l < h->heap_size && (HEAP_KEY(h, l) > HEAP_KEY(h, i))) largest = l; else largest = i; if (r < h->heap_size && (HEAP_KEY(h, r) > HEAP_KEY(h, largest))) largest = r; if (largest != i) { HEAP_SWAP_NODES(i,largest); heap_max_heapify (h, largest); } /* todo: set was_heapified to true */ return HEAP_ERR_OK; }
void heapsort(int *v, int size) { int i; heap_build_max_heap(v, size); for (i = size - 1; i > 0; i--) { swap(v, 0, i); size--; heap_max_heapify(v, size, 0); } }
int heap_extract_max(struct vector *v) { int max; if (v->size < 1) return -1; max = v->v[0]; v->v[0] = v->v[v->size - 1]; v->size--; heap_max_heapify(v->v, v->size, 0); return max; }
void heap_max_heapify(int *v, int size, int i) { int l, r; int largest; l = HEAP_LEFT(i); r = HEAP_RIGHT(i); if (l < size && v[l] > v[i]) largest = l; else largest = i; if (r < size && v[r] > v[largest]) largest = r; if (largest != i) { swap(v, i, largest); heap_max_heapify(v, size, largest); } }
/** * @brief heapify heap data elements * * This routine heapifies the heap elements in the heap h. * * @param[in] h The heap to build * @param[in] data Array of data elements * @param[in] num Number of array elements */ HEAP_ERR_E heap_build (HEAP_T* h) { unsigned long i; HEAP_ERR_E err; /* todo: use was_heapified to skip this if already a heap */ for (i = h->heap_size/2; i >= 1; i--) { if (h->type == DS_HEAP_MAX) { if (HEAP_ERR_ERR == (err = heap_max_heapify (h, i-1))) return HEAP_ERR_ERR; } else { if (HEAP_ERR_ERR == (err = heap_min_heapify (h, i-1))) return HEAP_ERR_ERR; } } return HEAP_ERR_OK; }
/** * @brief extract the maximum element from the heap * * @param[in] g The heap to operate on * @param[out] data The application object attached with the key * @param[out] key The application object key * @return HEAP_ERR_E */ HEAP_ERR_E heap_extract_max (HEAP_T* h, void** data, unsigned long* key) { /* todo: check was_heapified */ if (h->type != DS_HEAP_MAX) return HEAP_ERR_WRONG_TYPE; if (h->heap_size < 1) { *data = NULL; return HEAP_ERR_UNDERFLOW; } *data = h->nodes[0]->data; *key = h->nodes[0]->key; h->nodes[0]->data = h->nodes[h->heap_size-1]->data; h->nodes[0]->key = h->nodes[h->heap_size-1]->key; h->nodes[0]->i = h->nodes[h->heap_size-1]->i; if (h->nodes[0]->i) *h->nodes[0]->i = 0; h->heap_size--; heap_max_heapify (h, 0); return HEAP_ERR_OK; }
void heap_build_max_heap(int *v, int size) { int i; for (i = (size/2) - 1; i >= 0; i--) heap_max_heapify(v, size, i); }