/** Decreases key by index * Have amortized time of O(1) */ void decrease_key(int index, ScalarType& key) { fibonacci_heap_node* parent; if(index >= max_num_nodes || index < 0) return; if(nodes[index]->index == -1) return; // node is empty if(key > nodes[index]->key) return; nodes[index]->key = key; parent = nodes[index]->parent; if(parent != NULL && nodes[index]->key < parent->key) { cut(nodes[index], parent); cascading_cut(parent); } if(nodes[index]->key < min_root->key) min_root = nodes[index]; }
void FibHeap<Key, Data, Compare>::cascading_cut(Node* child) noexcept{ Node* parent = child->parent; if (parent!=nullptr){ if (child->mark==false) child->mark = true; else{ cut(child, parent); cascading_cut(parent); } } }
/** * It does recursive cuts while there is a parent with a mark = true * Cost: O(log n) * Pre: node x to cut upwards **/ void fib_heap::cascading_cut(node_t* x) { node_t* parent_x = x->parent; if (parent_x != nullptr) { if (x->mark == false) x->mark = true; else { cut(x); cascading_cut(parent_x); } } }
/** * Switching key of elem, pointed by pos, in new_key * Cost: Worst case: O (log n); amortized: O(1) * Pre: @pos is pointing to the elem whose key wants to be changed * Post: fib_heap where elem now has the new_key value **/ void fib_heap::decreaseKey( node_t* pos, int new_key) { if (new_key >= pos->key) return; //DO NOTHING else { pos->key = new_key; node_t *pos_parent = pos->parent; if (pos_parent != nullptr && new_key < pos_parent->key) { cut(pos); cascading_cut(pos_parent); } if (pos->key < min->key) min = pos; } }
void FibHeap<Key, Data, Compare>::decrease_key(Node* node, Key new_key) { if (node == nullptr) throw logic_error("There is no node to decrease key."); if (Compare()(node->key, new_key)) return; node->key = new_key; Node* parent = node->parent; if (parent==nullptr){ if (Compare()(node->key, root->key)) root = node; }else{ if (Compare()(node->key, parent->key)){ cut(node, parent); cascading_cut(parent); } } }
static void cascading_cut(fibonacci_heap* heap, heap_node* y) { heap_node* z = y->parent; if (z) { if (y->marked) { cut(heap, y, z); cascading_cut(heap, z); } else { y->marked = true; } } }
void cascading_cut(fibonacci_heap_node* tree) { fibonacci_heap_node *temp; temp = tree->parent; if(temp != NULL) { if(!tree->marked) { tree->marked = true; } else { cut(tree, temp); cascading_cut(temp); } } }
bool fibonacci_heap_decrease_key(fibonacci_heap* heap, void* element, void* priority) { heap_node* x; heap_node* y; if (!heap) { return false; } x = unordered_map_get(heap->node_map, element); if (!x) { return false; } if (heap->key_compare_function(x->priority, priority) <= 0) { /* Cannot improve priority of the input element. */ return false; } x->priority = priority; y = x->parent; if (y && heap->key_compare_function(x->priority, y->priority) < 0) { cut(heap, x, y); cascading_cut(heap, y); } if (heap->key_compare_function(x->priority, heap->minimum_node->priority) < 0) { heap->minimum_node = x; } return true; }