/* join two trees into one keeping the order rules */ node * join_trees (node *a, node *b) { if (a == NULL) return b; if (b == NULL) return a; b = insert_node (&b, a->key); b->left = join_trees (a->left, b->left); b->right = join_trees (a->right, b->right); free (a); return b; }
int main () { node *a = NULL; node *b = NULL; insert_node (&a, 8); insert_node (&a, 10); insert_node (&a, 6); insert_node (&a, 4); insert_node (&a, 7); insert_node (&b, 5); insert_node (&b, 1); insert_node (&b, 9); insert_node (&b, 3); insert_node (&b, 2); printf ("show tree A:\n"); show (a, 0); printf ("show tree B:\n"); show (b, 0); printf ("validated A?: %s\n", validate_tree (a) ? "yes" : "no"); printf ("validated B?: %s\n\n", validate_tree (b) ? "yes" : "no"); join_trees (b, a); printf ("show joint tree:\n"); show (a, 0); printf ("validated?: %s\n", validate_tree (a) ? "yes\n" : "no\n"); destroy_tree (a); destroy_tree (b); return 0; }
item* delete_min(heap* h) { node* min_node = h->min_node; node* list_to_concat = NULL; if (min_node != NULL) { if (min_node->left_sibling == min_node) { // only one root h->min_node = NULL; list_to_concat = min_node->child; } else { // save an arbitrary reference to the new list list_to_concat = min_node->left_sibling; // remove min root from forest remove_node_in_list(min_node); if (min_node->child != NULL) { // If we have to append childs from the min root concat_list(list_to_concat, min_node->child); } } } h->rank = h->rank - 1; if (list_to_concat != NULL) { int mr = max_rank(h); node* ranks[mr]; //calloc? for (int i = 0; i < mr; i++) { ranks[i] = NULL; } node* last_ref = list_to_concat; //which is actually just a pointer to an item do { node* next_ref = last_ref->right_sibling; last_ref->parent = NULL; // remember to set parent 0 - all is root nodes last_ref->left_sibling = last_ref; last_ref->right_sibling = last_ref; node* this_ref = last_ref; node* existing_tree = ranks[this_ref->rank]; // a while is necessary if we join trees while (existing_tree != NULL) { ranks[this_ref->rank] = NULL; this_ref = join_trees(existing_tree, this_ref); existing_tree = ranks[this_ref->rank]; } ranks[this_ref->rank] = this_ref; last_ref = next_ref; } while (last_ref != list_to_concat); // this way, we go through the circular list, until we reach the starting point node* new_min_node = NULL; // set an arbitrary one for (int i = 0; i < mr; i++) { node* curr_tree = ranks[i]; if (new_min_node == NULL) { new_min_node = curr_tree; } else if (curr_tree != NULL) { concat_list(new_min_node, curr_tree); if (GT(new_min_node->key, curr_tree->key)) { new_min_node = curr_tree; } } } h->min_node = new_min_node; } if (min_node != NULL) { item* val = min_node->item; free(min_node); return val; } else { return NULL; } }