static void heap_fix_top_down (struct heap *heap, unsigned pos) { for (;;) { if (heap_get_left_child (pos) >= heap->elem_cnt) break; if (heap_less (heap, heap_get_left_child (pos), pos)) { heap_swap (heap, heap_get_left_child (pos), pos); pos = heap_get_left_child (pos); continue; } if (heap_get_right_child (pos) >= heap->elem_cnt) break; if (heap_less (heap, heap_get_right_child (pos), pos)) { heap_swap (heap, heap_get_left_child (pos), pos); pos = heap_get_left_child (pos); continue; } break; } }
/** Hace bajar el nodo en index hasta la posicion que le corresponde */ void heap_sift_down(Heap* heap, size_t index) { /** El índice actual del nodo */ size_t node_i = index; /* Llevamos a cabo la operación hasta que se indique lo contrario */ while(true) { /* Los indices de ambos hijos del nodo */ size_t left_i = heap_left_child_of(node_i); size_t right_i = heap_right_child_of(node_i); /* Si no tiene hijo izquierdo, no tiene a donde bajar */ if(left_i >= heap -> count) break; /* El nodo solo tiene hijo izquierdo */ if(right_i == heap -> count) { /* Si el hijo es mayor que el padre */ if(heap -> array[left_i].key > heap -> array[node_i].key) { /* Se intercambian */ heap_swap(heap, node_i, left_i); } /* Como no tenía hijo derecho, no tiene a donde más bajar */ break; } /* El nodo tiene dos hijos */ else { /* Las key de los hijos */ int left_key = heap -> array[left_i].key; int right_key = heap -> array[right_i].key; /* El indice del hijo con la key mas alta */ int max_i = left_key > right_key ? left_i : right_i; /* Si el hijo más grande es mayor que el padre */ if(heap -> array[max_i].key > heap -> array[node_i].key) { /* Se intercambian */ heap_swap(heap, node_i, max_i); /* Indicamos que el indice cambio y seguimos bajandolo */ node_i = max_i; } /* Si no, no hay nada más que hacer */ else break; } } }
static int heap_heapify(Heap *h,int idx) { int l,r,largest; HeapInternCmp cmp_func; DBG(debug("heap_heapify(h=%p,idx=%d)\n",h,idx)); l = HLEFT(idx); r = HRIGHT(idx); LLOG(l); LLOG(r); if (h->hpMode == HEAP_MAXIMIZE) cmp_func = heap_larger; else cmp_func = heap_smaller; if (l <= HSIZE(h) && cmp_func(h,HARRAY(h,l),HARRAY(h,idx))) largest = l; else largest = idx; if (r <= HSIZE(h) && cmp_func(h,HARRAY(h,r),HARRAY(h,largest))) largest = r; if (largest != idx) { heap_swap(h,idx,largest); return heap_heapify(h,largest); } return 0; }
int minheap_add (heap_t *heap, elem_t elem) { ofs_t loc, par; if (heap->cnt >= HEAP_SIZE) return -ENOMEM; loc = heap->cnt; heap->cnt ++; /* place new element in the next spot */ heap->data[loc] = elem; /* while we have a parent move to it and see if order is maintained */ while ((par = heap_parent_of (heap, loc)) != OFS_INVAL) { key_t par_key = elem_key (heap->data[par]); key_t loc_key = elem_key (heap->data[loc]); /* parent must be smaller */ if (par_key < loc_key) goto done; /* if not then swap the elements */ heap_swap (heap, par, loc); /* now move up */ loc = par; } done: return 0; }
static inline void max_heapify(struct ast_heap *h, int i) { for (;;) { int l = left_node(i); int r = right_node(i); int max; if (l <= h->cur_len && h->cmp_fn(heap_get(h, l), heap_get(h, i)) > 0) { max = l; } else { max = i; } if (r <= h->cur_len && h->cmp_fn(heap_get(h, r), heap_get(h, max)) > 0) { max = r; } if (max == i) { break; } heap_swap(h, i, max); i = max; } }
void heap_down(int i) { int a = 2*i+1; int b = 2*i+2; if(b < heapsize) { if(heap_val[b] < heap_val[a] && heap_val[b] < heap_val[i]) { heap_swap(i, b); heap_down(b); return; } } if(a < heapsize && heap_val[a] < heap_val[i]) { heap_swap(i, a); heap_down(a); } }
/** Hace subir el nodo en index hasta la posicion que le corresponde */ void heap_sift_up(Heap* heap, size_t index) { /* El índice actual del nodo */ size_t node_i = index; /* Repetimos la operacion hasta que se indique lo contrario */ while(true) { /* Si el indice es 0, no tiene a donde más subir */ if(!node_i) break; /* Obtenemos el indice del padre de este nodo */ size_t parent_i = heap_parent_of(node_i); /* Si el hijo es mayor que el padre */ if(heap -> array[node_i].key > heap -> array[parent_i].key) { /* Se intercambian */ heap_swap(heap, node_i, parent_i); /* Indicamos que cambió el indice y seguimos subiendolo */ node_i = parent_i; } /* Si son iguales no hay nada mas que hacer */ else break; } }
static void heap_push_down(size_t i) { size_t c, smallest; assert(i < timer_context.n); for (;;) { smallest = i; c = i * 2 + 1; if (c >= timer_context.n) break; if (time_after(timer_context.heap[smallest]->expires, timer_context.heap[c]->expires)) { smallest = c; } if (++c < timer_context.n) { if (time_after(timer_context.heap[smallest]->expires, timer_context.heap[c]->expires)) { smallest = c; } } if (i == smallest) break; heap_swap(i, smallest); i = smallest; } }
static unsigned bubble_up(heap_t heap, unsigned long i) { while (i > 1 && heap->cmp(heap_get(heap, parent_node(i)), heap_get(heap, i)) < 0) { heap_swap(heap, parent_node(i), i); i = parent_node(i); } return i; }
static int bubble_up(struct ast_heap *h, int i) { while (i > 1 && h->cmp_fn(heap_get(h, parent_node(i)), heap_get(h, i)) < 0) { heap_swap(h, i, parent_node(i)); i = parent_node(i); } return i; }
/** Elimina del heap el elemento situado en index */ void heap_remove_at(Heap* heap, size_t index) { /* Hacemos subir al nodo a la cabeza del heap */ heap_update_key(heap, index, INT_MAX); /* Ponemos el último elemento en la cabeza del heap */ heap_swap(heap, 0, --heap -> count); /* Lo hacemos bajar a donde le correspnde */ heap_sift_down(heap, 0); }
struct heapnode heap_extract_min(struct heap *h) { if (h->nnodes == 0) return (struct heapnode){0, NULL}; struct heapnode minnode = h->nodes[1]; h->nodes[1] = h->nodes[h->nnodes]; h->Vtoidx[h->nodes[1].value] = 1; h->nnodes--; heap_heapify(h, 1); return minnode; } void heap_heapify(struct heap *h, int index) { for (;;) { int left = 2 * index; int right = 2 * index + 1; // Find largest key: A[index], A[left] and A[right] int largest = index; if (left <= h->nnodes && h->nodes[largest].key > h->nodes[left].key) { largest = left; } if (right <= h->nnodes && h->nodes[largest].key > h->nodes[right].key) { largest = right; } if (largest == index) break; heap_swap(h, index, largest); index = largest; } } int heap_decrease_key(struct heap *h, int value, int key) { int index = h->Vtoidx[value]; if (h->nodes[index].key < key) return -1; h->nodes[index].key = key; for ( ; index > 1 && h->nodes[index].key < h->nodes[index / 2].key; index = index / 2) { heap_swap(h, index, index / 2); } h->Vtoidx[value] = index; return 0; }
void heap_delmin(struct heap *h) { if(h->num == 0) return; if(h->num > 1) { heap_swap(HHEAD(h),HELEMENT(h,h->num)); } --h->num; _heap_bubble_down(h, 1); }
static void heap_fix_bottom_up (struct heap *heap, unsigned pos) { while (!heap_is_root (pos)) { if (!heap_less (heap, pos, heap_get_parent (pos))) break; heap_swap (heap, pos, heap_get_parent (pos)); pos = heap_get_parent (pos); } }
void heap_bubble_up(Heap* heap, int index) { if(index == 0) { return; } int compare = heap->comparator(heap_get(heap, index), heap_parent(heap, index)); if(compare <= 0) { heap_swap(heap, index, heap_parent_index(index)); heap_bubble_up(heap, heap_parent_index(index)); } }
static void heap_siftdown(heap_t *h, int k) { for ( ; ; ) { int p = (k - 1) / 2; /* parent */ if (k == 0 || heap_less(h, p, k)) { return; } heap_swap(h, k, p); k = p; } }
void heap_bubble_down(Heap* heap, int index) { if(heap_left_child_index(index) <= heap_last_index(heap)) { int left_compare = heap->comparator(heap_get(heap, index), heap_left_child(heap, index)); if(1 == left_compare) { heap_swap(heap, index, heap_left_child_index(index)); heap_bubble_down(heap, heap_left_child_index(index)); return; } } if(heap_right_child_index(index) <= heap_last_index(heap)) { int right_compare = heap->comparator(heap_get(heap, index), heap_right_child(heap, index)); if(1 == right_compare) { heap_swap(heap, index, heap_right_child_index(index)); heap_bubble_down(heap, heap_right_child_index(index)); return; } } return; }
void heap_hold(struct Heap *heap,int pos){ int left=2*pos+1,right=2*pos+2; int minpos=pos; if(right<heap->size && heap->data[right]->weight < heap->data[minpos]->weight) minpos=right; if(left<heap->size && heap->data[left]->weight < heap->data[minpos]->weight) minpos=left; if(minpos!=pos){ heap_swap(heap,minpos,pos); heap_hold(heap,minpos); } }
static inline void _heap_bubble_up(struct heap *h, int e) { int e1; while (e > 1) { e1 = e/2; if(h->cmp(*HELEMENT(h, e1),*HELEMENT(h,e)) < 0) break; heap_swap(HELEMENT(h,e),HELEMENT(h,e1)); e = e1; } }
void heap_delete(struct heap *h, int e) { heap_swap(HELEMENT(h, e), HELEMENT(h, h->num)); h->num--; if(h->cmp(*HELEMENT(h, e), *HELEMENT(h, h->num + 1)) < 0) _heap_bubble_up(h, e); else _heap_bubble_down(h, e); if ((h->num > INITIAL_HEAP_SIZE) && (h->num < h->max_size / HEAP_DECREASE_THRESHOLD)) { h->max_size = h->max_size / HEAP_INCREASE_STEP; h->data = realloc(h->data, (h->max_size + 1) * sizeof(heap_val_t)); } }
static inline void _heap_bubble_down(struct heap *h, int e) { int e1; for (;;) { e1 = 2*e; if(e1 > h->num) break; if((h->cmp(*HELEMENT(h, e),*HELEMENT(h,e1)) < 0) && (e1 == h->num || (h->cmp(*HELEMENT(h, e),*HELEMENT(h,e1+1)) < 0))) break; if((e1 != h->num) && (h->cmp(*HELEMENT(h, e1+1), *HELEMENT(h,e1)) < 0)) e1++; heap_swap(HELEMENT(h,e),HELEMENT(h,e1)); e = e1; } }
void heap_sort(int array[], int size) { int start, end; for (start = (size-2)/2; start >= 0; start--) { sift_down(array, start, size); } for (end = size-1; end > 0; end--) { heap_swap(&array[end], &array[0]); sift_down(array, 0, end); } }
void heap_sort(void *base, unsigned int num_elem, size_t size_elem, compare_func comp) { struct heap heap; unsigned int i; heap_init(&heap, base, num_elem, size_elem, comp); for (i = num_elem; i >= 2; i--) { heap_swap(&heap, 1, i); heap.elem_count -= 1; heap_order(&heap, 1); } }
static void max_heapify(heap_t heap, unsigned long i) { for (;;) { unsigned long l = left_node(i), r = right_node(i), max; max = l <= heap->curr && heap->cmp(heap_get(heap, l), heap_get(heap, i)) > 0 ? l : i; if (r <= heap->curr && heap->cmp(heap_get(heap, r), heap_get(heap, max)) > 0) max = r; if (max == i) break; heap_swap(heap, i, max); i = max; } }
static void heap_pull_up(size_t i) { size_t p; while (i > 0) { p = (i - 1) / 2; if (!time_before(timer_context.heap[i]->expires, timer_context.heap[p]->expires)) { break; } heap_swap(i, p); i = p; } }
/** Extrae el elemento de mayor key del heap. Retorna NULL si esta vacio */ void* heap_extract(Heap* heap) { /* Si no tiene elementos, retorna NULL */ if(!heap -> count) return NULL; /* Obtenemos el puntero a retornar */ void* max = heap -> array[0].content; /* Actualizamos el contador */ heap -> count--; /* Ponemos el último elemento en la cabeza del heap */ heap_swap(heap, 0, heap -> count); /* Lo hacemos bajar a donde le correspnde */ heap_sift_down(heap, 0); /* Retornamos el puntero con mayor key */ return max; }
/* * Remove a timer from the heap. Do this by swapping it with the element * in the last position, then shortening the heap, then moving the * swapped element up or down to maintain the partial ordering. */ static void heap_delete(TimerHeap *heap, long index) { long last; gw_assert(index >= 0); gw_assert(index < heap->len); gw_assert(heap->tab[index]->index == index); last = heap->len - 1; heap_swap(heap, index, last); heap->tab[last]->index = -1; heap->len--; if (index != last) heap_adjust(heap, index); }
int heap_insert(struct heap *h, int key, int value) { if (h->nnodes >= h->maxsize) { /* Heap overflow */ return -1; } h->nnodes++; h->nodes[h->nnodes].key = key; h->nodes[h->nnodes].value = value; h->Vtoidx[value] = h->nnodes; // HeapifyUp int i; for (i = h->nnodes; i > 1 && h->nodes[i].key < h->nodes[i / 2].key; i = i / 2) { heap_swap(h, i, i / 2); h->Vtoidx[value] = i / 2; } return 0; }
void sift_down(int array[], int start, int end) { int root = start; while (root*2+1 < end) { int child = 2*root + 1; if ((child + 1 < end) && array[child] < array[child+1]) { child += 1; } if (array[root] < array[child]) { heap_swap(&array[child], &array[root]); root = child; } else return; } }
static void heap_siftup(heap_t *h, int k) { for ( ; ; ) { int l, r, s; l = k * 2 + 1; /* left child */ r = k * 2 + 2; /* right child */ /* find the smallest of the three */ s = k; if (l < h->len && heap_less(h, l, s)) s = l; if (r < h->len && heap_less(h, r, s)) s = r; if (s == k) { return; /* statisfies the heap property */ } heap_swap(h, k, s); k = s; } }