extern gdsl_element_t gdsl_interval_heap_remove_max (gdsl_interval_heap_t heap) { gdsl_element_t e = NULL; assert (heap != NULL); if (heap->card == 0) { return NULL; } // if there's only one element left, we must return the minimum // which is naturally also the maximum if (heap->card == 1) { e = heap->nodes[ INDEX_MIN () ]; heap->card--; return e; } e = heap->nodes [ INDEX_MAX () ]; heap->nodes [ INDEX_MAX () ] = heap->nodes [ LAST_INDEX (heap->card) ]; heap->card--; taslactite_max (heap->nodes, LAST_INDEX (heap->card), LAST_INDEX (1), heap->comp_f); //gdsl_check_interval_heap_integrity(heap); //fprintf(stderr, "returning max: %x size: %d\n", e, heap->card); return e; }
static void taslacmite_max (gdsl_element_t* t, ulong k, gdsl_compare_func_t comp_f) { /* * Traverse up the tree comparing and swapping maximum values. */ gdsl_element_t v; v = t[k]; while (k > INDEX_MAX () && comp_f (t[PARENT_MAX (k)], v) < 0) { t[ k ] = t[ PARENT_MAX (k) ]; k = PARENT_MAX (k); } t[k] = v; }
extern gdsl_element_t gdsl_interval_heap_get_max (gdsl_interval_heap_t heap) { gdsl_element_t e = NULL; assert (heap != NULL); if (heap->card == 0) { return NULL; } if (heap->card == 1) { e = heap->nodes [ INDEX_MIN () ]; } else { e = heap->nodes [ INDEX_MAX () ]; } return e; }
extern gdsl_element_t gdsl_interval_heap_insert (gdsl_interval_heap_t heap, void* value) { gdsl_element_t e; assert (heap != NULL); e = (heap->alloc_f) (value); if (e == NULL) { return NULL; } if (heap->card == heap->size) { // the heap is full, so remove the min value and replace // it with the newly inserted value gdsl_element_t e1 = heap->nodes[ INDEX_MIN () ]; // the value to be inserted is smaller than the smallest, so we just // return it and do nothing. if (heap->comp_f(e, e1) <= 0) { return e; } // we're inserting a node that's greater than the max // that means the max has to become the new min if (heap->comp_f(e, heap->nodes[ INDEX_MAX() ]) > 0) { heap->nodes[ INDEX_MIN() ] = heap->nodes[INDEX_MAX ()]; heap->nodes[ INDEX_MAX() ] = e; } else { heap->nodes [ INDEX_MIN() ] = e; } taslactite_min (heap->nodes, LAST_INDEX (heap->card), LAST_INDEX (1), heap->comp_f); return e1; } if (3 + heap->card > heap->allocated) { heap->nodes = (gdsl_element_t*) realloc (heap->nodes, ((4 + (2 * heap->card)) * sizeof (gdsl_element_t))); heap->allocated = (4 + (2 * heap->card)); } if (heap->nodes == NULL) { (heap->free_f) (e); return NULL; } heap->card++; //insert into the last place available //if it's in the min position, it needs to be duplicated //in the max heap->nodes [ LAST_INDEX (heap->card) ] = e; heap->nodes [ MAX_NODE (LAST_INDEX (heap->card)) ] = e; fix (heap->nodes, MIN_NODE (LAST_INDEX (heap->card)), heap->comp_f); taslacmite_min (heap->nodes, MIN_NODE (LAST_INDEX (heap->card) ), heap->comp_f); taslacmite_max (heap->nodes, LAST_INDEX (heap->card), heap->comp_f); return NULL; }
static void check_integrity (const gdsl_interval_heap_t heap) { int i, j; for (i = 1; i <= heap->card; i++) { if (i % 2 == 0) { int comp = heap->comp_f (heap->nodes[ LAST_INDEX (i-1) ], heap->nodes[ LAST_INDEX (i) ]); //printf("comp %d\n", comp); assert (comp <= 0); } if (LAST_INDEX (i) > INDEX_MAX ()) { int comp1 = heap->comp_f (heap->nodes[ LAST_INDEX (i) ], heap->nodes[ PARENT_MIN (LAST_INDEX (i)) ]); int comp2 = heap->comp_f (heap->nodes[ LAST_INDEX (i) ], heap->nodes[ PARENT_MAX (LAST_INDEX (i)) ]); //printf("LAST_INDEX(i): %lu PARENT_MIN: %lu\n", LAST_INDEX(i), PARENT_MIN( LAST_INDEX(i) )); //printf("LAST_INDEX(i): %lu PARENT_MAX: %lu\n", LAST_INDEX(i), PARENT_MAX( LAST_INDEX(i) )); if (comp1 < 0) { int li = LAST_INDEX (i); int pi = PARENT_MIN (li); fprintf (stderr, "min child t[%d]: %d parent t[%d]: %d\n", li, vti (heap->nodes[li]), pi, vti (heap->nodes[pi])); raw_dump (heap); } if (comp2 > 0) { int li = LAST_INDEX (i); int pi = PARENT_MAX (li); fprintf (stderr, "max child t[%d]: %d parent t[%d]: %d\n", li, vti (heap->nodes[li]), pi, vti (heap->nodes[pi])); raw_dump (heap); } assert (comp1 >= 0); assert (comp2 <= 0); } for (j = i+ 1; j <= heap->card; j++) { if (heap->nodes[ LAST_INDEX(i) ] == heap->nodes[ LAST_INDEX(j) ]) { fprintf(stderr, "IDENTICAL VALUES: %d %d\n", i, j); // N.B. I don't want any exit in my code! :) // exit (1); return 1; // I prefer a simple return (N. D.) } assert (heap->nodes[ LAST_INDEX (i) ] != heap->nodes[ LAST_INDEX (j) ]); } } //printf("passed integrity check\n"); }