fh_decrease_key() - decreases the key used for vertex, vertex_no, to * new_value. No check is made to ensure that new_value is in-fact less than * the current value so it is up to the user of this function to ensure that * it is. */
| 197 | * it is. |
| 198 | */ |
| 199 | void fh_decrease_key(fheap_t *h, int vertex_no, long new_value) |
| 200 | { |
| 201 | fheap_node_t *cut_node, *parent, *new_roots, *r, *l; |
| 202 | int prev_rank; |
| 203 | |
| 204 | #if FHEAP_DUMP |
| 205 | printf("decrease_key on vn = %d, ", vertex_no); |
| 206 | #endif |
| 207 | |
| 208 | /* Obtain a pointer to the decreased node and its parent then decrease the |
| 209 | * nodes key. |
| 210 | */ |
| 211 | cut_node = h->nodes[vertex_no]; |
| 212 | parent = cut_node->parent; |
| 213 | cut_node->key = new_value; |
| 214 | |
| 215 | /* No reinsertion occurs if the node changed was a root. */ |
| 216 | if(!parent) { |
| 217 | #if FHEAP_DUMP |
| 218 | printf("decrease_key-exited, "); |
| 219 | #endif |
| 220 | return; |
| 221 | } |
| 222 | |
| 223 | /* Update the left and right pointers of cut_node and its two neighbouring |
| 224 | * nodes. |
| 225 | */ |
| 226 | l = cut_node->left; |
| 227 | r = cut_node->right; |
| 228 | l->right = r; |
| 229 | r->left = l; |
| 230 | cut_node->left = cut_node->right = cut_node; |
| 231 | |
| 232 | /* Initially the list of new roots contains only one node. */ |
| 233 | new_roots = cut_node; |
| 234 | |
| 235 | /* While there is a parent node that is marked a cascading cut occurs. */ |
| 236 | while(parent && parent->marked) { |
| 237 | |
| 238 | /* Decrease the rank of cut_node's parent an update its child pointer. |
| 239 | */ |
| 240 | parent->rank--; |
| 241 | if(parent->rank) { |
| 242 | if(parent->child == cut_node) parent->child = r; |
| 243 | } |
| 244 | else { |
| 245 | parent->child = NULL; |
| 246 | } |
| 247 | |
| 248 | /* Update the cut_node and parent pointers to the parent. */ |
| 249 | cut_node = parent; |
| 250 | parent = cut_node->parent; |
| 251 | |
| 252 | /* Update the left and right pointers of cut_nodes two neighbouring |
| 253 | * nodes. |
| 254 | */ |
| 255 | l = cut_node->left; |
| 256 | r = cut_node->right; |
no test coverage detected