static void fibheap_cascading_cut(fibheap_t *fib, fibnode_t *node) { fibnode_t *parent; while ((parent = node->parent) != NULL) { if (node->mark == 0) { node->mark = 1; return; } fibheap_cut(fib, node, parent); node = parent; } }
static int __fibheap_decrease_key(fibheap_t *fib, fibnode_t *node, long key) { fibnode_t *parent = node->parent; node->key = key; if (parent && node->key <= parent->key) { fibheap_cut(fib, node, parent); fibheap_cascading_cut(fib, parent); } if (node->key <= fib->min->key) fib->min = node; return 0; }
static void fibheap_cascading_cut (fibheap_t heap, fibnode_t y) { fibnode_t z; while ((z = y->parent) != NULL) { if (y->mark == 0) { y->mark = 1; return; } else { fibheap_cut (heap, y, z); y = z; } } }
/* Replace both the KEY and the DATA associated with NODE. */ void * fibheap_replace_key_data (fibheap_t heap, fibnode_t node, fibheapkey_t key, void *data) { void *odata; fibheapkey_t okey; fibnode_t y; /* If we wanted to, we could actually do a real increase by redeleting and inserting. However, this would require O (log n) time. So just bail out for now. */ if (fibheap_comp_data (heap, key, data, node) > 0) { fprintf( stderr, "Unhandled case of fibheap key increase: bailing\n"); return NULL; } odata = node->data; okey = node->key; node->data = data; node->key = key; y = node->parent; if (okey == key) return odata; /* These two compares are specifically <= 0 to make sure that in the case of equality, a node we replaced the data on, becomes the new min. This is needed so that delete's call to extractmin gets the right node. */ if (y != NULL && fibheap_compare (heap, node, y) <= 0) { fibheap_cut (heap, node, y); fibheap_cascading_cut (heap, y); } if (fibheap_compare (heap, node, heap->min) <= 0) heap->min = node; return odata; }