Пример #1
0
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;
    }
}
Пример #2
0
/** 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;
        }
    }
}
Пример #3
0
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;
}
Пример #4
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;
}
Пример #5
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;
	}
}
Пример #6
0
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);
    }
}
Пример #7
0
/** 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;
    }
}
Пример #8
0
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;
	}
}
Пример #9
0
Файл: heap.c Проект: kcyeu/xcb
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;
}
Пример #10
0
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;
}
Пример #11
0
/** 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);
}
Пример #12
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;
}
Пример #13
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);
}
Пример #14
0
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);
    }
}
Пример #15
0
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));
  }
}
Пример #16
0
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;
    }
}
Пример #17
0
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);
    }
}
Пример #19
0
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;
	}

}
Пример #20
0
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));
	}
}
Пример #21
0
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;
	}
}
Пример #22
0
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);
    }

}
Пример #23
0
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);
    }
}
Пример #24
0
Файл: heap.c Проект: kcyeu/xcb
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;
	}
}
Пример #25
0
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;
	}
}
Пример #26
0
/** 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;
}
Пример #27
0
/*
 * 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);
}
Пример #28
0
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;
}
Пример #29
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;
    }
}
Пример #30
0
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;
    }
}