Games-EternalLands
view release on metacpan or search on metacpan
src/bheap.c view on Meta::CPAN
}
/* bh_insert() inserts an item and its key value into the binary heap pointed
* to by h.
*/
void bh_insert(bheap_t *h, int item, long key)
{
/* i - insertion point
* j - parent of i
* y - parent's entry in the heap.
*/
int i, j;
bheap_item_t y;
/* i initially indexes the new entry at the bottom of the heap. */
i = ++(h->n);
/* Stop if the insertion point reaches the top of the heap. */
while(i >= 2) {
/* j indexes the parent of i. y is the parent's entry. */
j = i / 2;
y = h->a[j];
/* We have the correct insertion point when the item's key is >= parent
* Otherwise we move the parent down and insertion point up.
*/
h->key_comps++;
if(key >= y.key) break;
h->a[i] = y;
h->p[y.item] = i;
i = j;
}
/* Insert the new item at the insertion point found. */
h->a[i].item = item;
h->a[i].key = key;
h->p[item] = i;
}
/* bh_delete() deletes an item from the binary heap pointed to by h.
*/
void bh_delete(bheap_t *h, int item)
{
int n;
int p;
/* Decrease the number of entries in the heap and record the position of
* the item to be deleted.
*/
n = --(h->n);
p = h->p[item];
/* Heap needs adjusting if the position of the deleted item was not at the
* end of the heap.
*/
if(p <= n) {
/* We put the item at the end of the heap in the place of the deleted
* item and sift-up or sift-down to relocate it in the correct place in
* the heap.
*/
h->key_comps++;
if(h->a[p].key <= h->a[n + 1].key) {
h->a[p] = h->a[n + 1];
h->p[h->a[p].item] = p;
bh_siftup(h, p, n);
}
else {
/* Use insert to sift-down, temporarily adjusting the size of the
* heap for the call to insert.
*/
h->n = p - 1;
bh_insert(h, h->a[n + 1].item, h->a[n+1].key);
h->n = n;
}
}
}
/* bh_decrease_key() decreases the value of 'item's key and then performs
* sift-down until 'item' has been relocated to the correct position in the
* binary heap.
*/
void bh_decrease_key(bheap_t *h, int item, long new_key)
{
int n;
n = h->n;
h->n = h->p[item] - 1;
bh_insert(h, item, new_key);
h->n = n;
}
/*** Definitions for internal functions ***/
/* siftup() considers the sub-tree rooted at p that ends at q and moves
* the root down, sifting up the minimum child until it is located in the
* correct part of the binary heap.
*/
void bh_siftup(bheap_t *h, int p, int q)
{
/* y - the heap entry of the root.
* j - the current insertion point for the root.
* k - the child of the insertion point.
* z - heap entry of the child of the insertion point.
*/
int j, k;
bheap_item_t y, z;
/* Get the value of the root and initialise the insertion point and child.
*/
y = h->a[p];
j = p;
k = 2 * p;
/* sift-up only if there is a child of the insertion point. */
while(k <= q) {
/* Choose the minimum child unless there is only one. */
z = h->a[k];
if(k < q) {
h->key_comps++;
if(z.key > h->a[k + 1].key) z = h->a[++k];
}
/* We stop if the insertion point for the root is in the correct place.
* Otherwise the child goes up and the root goes down. (i.e. swap)
*/
if(y.key <= z.key) break;
h->a[j] = z;
h->p[z.item] = j;
j = k;
k = 2 * j;
}
/* Insert the root in the correct place in the heap. */
h->a[j] = y;
( run in 1.366 second using v1.01-cache-2.11-cpan-5511b514fd6 )