/* fh_insert() - creates and inserts new a node representing vertex_no with key * k into the heap h. */ void fh_insert(fheap_t *h, int vertex_no, double k) { // printf("heap:insert %d\n", vertex_no); fheap_node_t *newNode; #if FHEAP_DUMP printf("insert, "); #endif /* Create an initialise the new node. */ newNode = (fheap_node_t*) malloc(sizeof(fheap_node_t)); newNode->child = NULL; newNode->left = newNode->right = newNode; newNode->rank = 0; newNode->vertex_no = vertex_no; newNode->key = k; /* Maintain a pointer vertex_no's new node in the heap. */ h->nodes[vertex_no] = newNode; /* Meld the new node into the heap. */ fh_meld(h, newNode); /* Update the heaps node count. */ h->n++; #if FHEAP_DUMP printf("insert-exited, "); #endif }
/* fh_insert() - creates and inserts New a node representing vertex_no with key * k into the heap h. */ void fh_insert(fheap_t *h, long vertex_no, float k) { fheap_node_t *New; #if FHEAP_DUMP printf("insert, "); #endif /* Create an initialise the New node. */ New = (fheap_node_t*)malloc(sizeof(fheap_node_t)); New->child = NULL; New->left = New->right = New; New->rank = 0; New->vertex_no = vertex_no; New->key = k; /* Maintain a pointer vertex_no's New node in the heap. */ h->nodes[vertex_no] = New; /* Meld the New node into the heap. */ fh_meld(h, New); /* Update the heaps node count. */ h->n++; #if FHEAP_DUMP printf("insert-exited, "); #endif }
/* fh_delete_min() - deletes the minimum node from the heap pointed to by h and * returns its vertex number. */ int fh_delete_min(fheap_t *h) { // printf("heap:delete_min"); fheap_node_t *min_node, *child, *next; double k, k2; int r, v, vertex_no; #if FHEAP_DUMP printf("delete_min, "); #endif /* First we determine the maximum rank in the heap. */ v = h->value; r = -1; while(v) { v = v >> 1; r++; }; /* Now determine which root node is the minimum. */ min_node = h->trees[r]; k = min_node->key; while(r > 0) { r--; next = h->trees[r]; if(next) { if((k2 = next->key) < k) { k = k2; min_node = next; } h->key_comps++; } } /* We remove the minimum node from the heap but keep a pointer to it. */ r = min_node->rank; h->trees[r] = NULL; h->value -= (1 << r); child = min_node->child; if(child) fh_meld(h, child); /* Record the vertex no of the old minimum node before deleting it. */ vertex_no = min_node->vertex_no; h->nodes[vertex_no] = NULL; free(min_node); h->n--; #if FHEAP_DUMP printf("delete_min-exited, "); #endif // printf(": %d\n", vertex_no); return vertex_no; }
/* 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. */ void fh_decrease_key(fheap_t *h, int vertex_no, double new_value) { fheap_node_t *cut_node, *parent, *new_roots, *r, *l; int prev_rank; #if FHEAP_DUMP printf("decrease_key on vn = %d, ", vertex_no); #endif /* Obtain a pointer to the decreased node and its parent then decrease the * nodes key. */ cut_node = h->nodes[vertex_no]; parent = cut_node->parent; cut_node->key = new_value; /* No reinsertion occurs if the node changed was a root. */ if(!parent) { #if FHEAP_DUMP printf("decrease_key-exited, "); #endif return; } /* Update the left and right pointers of cut_node and its two neighbouring * nodes. */ l = cut_node->left; r = cut_node->right; l->right = r; r->left = l; cut_node->left = cut_node->right = cut_node; /* Initially the list of new roots contains only one node. */ new_roots = cut_node; /* While there is a parent node that is marked a cascading cut occurs. */ while(parent && parent->marked) { /* Decrease the rank of cut_node's parent an update its child pointer. */ parent->rank--; if(parent->rank) { if(parent->child == cut_node) parent->child = r; } else { parent->child = NULL; } /* Update the cut_node and parent pointers to the parent. */ cut_node = parent; parent = cut_node->parent; /* Update the left and right pointers of cut_nodes two neighbouring * nodes. */ l = cut_node->left; r = cut_node->right; l->right = r; r->left = l; /* Add cut_node to the list of nodes to be reinserted as new roots. */ l = new_roots->left; new_roots->left = l->right = cut_node; cut_node->left = l; cut_node->right = new_roots; new_roots = cut_node; } /* If the root node is being relocated then update the trees[] array. * Otherwise mark the parent of the last node cut. */ if(!parent) { prev_rank = cut_node->rank + 1; h->trees[prev_rank] = NULL; h->value -= (1 << prev_rank); } else { /* Decrease the rank of cut_node's parent an update its child pointer. */ parent->rank--; if(parent->rank) { if(parent->child == cut_node) parent->child = r; } else { parent->child = NULL; } parent->marked = 1; } /* Meld the new roots into the heap. */ fh_meld(h, new_roots); #if FHEAP_DUMP printf("decrease_key-exited, "); #endif }