void percolate_up(PQ* pq, int index) {
	int parent_index = index/2;
	
	if(pq->is_min_heap) {
		while(parent_index >= 1 && pq->heap[parent_index].priority > pq->heap[index].priority) {
			pq_swap(pq, index, parent_index);
			index = parent_index;
			parent_index = index/2;
		}
	}
	else {
		while(parent_index >= 1 && pq->heap[parent_index].priority < pq->heap[index].priority) {
			pq_swap(pq, index, parent_index);
			index = parent_index;
			parent_index = index/2;
		}
	}
}
Example #2
0
// Find parents and swap if necessary
void pq_bubble_up(prio_q* pq, int val)
{
    // Start with given node and its parent
    int p = pq_parent(val);
    if(p == -1) return;
    // Swap if needed
    if(pq->q[p] < pq->q[val])
    {
        pq_swap(pq, p, val);
        // Move to next pair
        pq_bubble_up(pq, p);
    }
}
Example #3
0
// Float an element down its subtree
int pq_bubble_down(prio_q* pq, int val)
{
    // Start with given node and its parent
    int l = pq_left_child(val);
    int r = pq_right_child(val);
    int m = val;

    if(l <= pq->n && pq->q[l] > pq->q[m]) m = l;
    if(r <= pq->n && pq->q[r] > pq->q[m]) m = r;
    if(m != val) 
    {
        pq_swap(pq, m, val);
        pq_bubble_down(pq, m);
    }
    return 0;
}
Example #4
0
void
pq_delete_min(PQ pq, void *retval)
{
    int floater;        /* previous loser floating down */
    int small_child;    /* smaller child of floater */

    assert(!pq_is_empty(pq));

    /* first copy out the winner */
    memcpy(retval, REF(pq, 0), pq->element_length);

    --(pq->n);

    if(pq_is_empty(pq)) {
        /* pq empty, nothing to do */
        return;
    }

    /* else */
    memcpy(REF(pq, 0), REF(pq, pq->n), pq->element_length);

    floater = 0;

    for(;;) {
        /* find smaller child of floater */
        if(Child(floater, 0) >= pq->n) {
            return;     /* no children, bail out */
        } else if(Child(floater, 1) >= pq->n) {
            small_child = Child(floater, 0);
        } else if(pq->compare(REF(pq, Child(floater, 0)), REF(pq, Child(floater, 1))) < 0) {
            small_child = Child(floater, 0);
        } else {
            small_child = Child(floater, 1);
        }

        /* is floater <= small_child? */
        if(pq->compare(REF(pq, floater), REF(pq, small_child)) <= 0) {
            /* yes, we are done */
            return;
        } else {
            /* no, swap and continue floating down */
            pq_swap(pq, floater, small_child);
            floater = small_child;
        }
    }
}
Example #5
0
/*
    Insert a value with attached min.prority in the priority queue.
    priority should be non-negative (>= 0)
    returns: 1 if successful, 0 if failed (pq is full)
*/
int pq_enqueue(struct priority_queue *pq, int val, int priority)
{
    if (pq == NULL) return 0;

    if (pq->size == MAX_HEAP_SIZE) return 0;

    if (priority < 0) return 0;

    int i;

    for (i = ++pq->size; priority < pq->heap[i / 2].priority; i /= 2)
        pq_swap(pq, i, i / 2);

    pq->heap[i].priority = priority;
    pq->heap[i].val = val;

    return 1;
}
Example #6
0
File: k9.c Project: hpersh/k9
static void
pq_insert(struct pq *pq, struct pq_node *nd)
{
  unsigned i, j;

  assert(pq->cnt < pq->size);

  i = pq->cnt;
  (pq->arr[i] = nd)->idx = i;
  nd->pq = pq;

  for ( ; i != 0; i = j) {
    j = (i - 1) >> 1;

    if ((*pq->cmp)(pq->arr[i], pq->arr[j]) >= 0)  break;

    pq_swap(pq, i, j);
  }

  ++pq->cnt;
}
void percolate_down_max(PQ* pq, int index) {
	int max, done = 0;
	int left_index = 2*index;
	int right_index = left_index+1;

	while(left_index <= pq->size && !done) {
		max = left_index;
		if(right_index <= pq->size)
			if(pq->heap[left_index].priority < pq->heap[right_index].priority)
				max = right_index;
		if(pq->heap[max].priority > pq->heap[index].priority) {
			pq_swap(pq, max, index);
			index = max;
		}
		else
			done = 1;

		left_index = 2*index;
		right_index = left_index+1;
	}	
}
Example #8
0
/*
    Removes the lowest priority object from the priority queue
    returns: 1 if successful, 0 if failed (pq is empty)

    note: may remove this from the spec (do cleanup)
*/
int pq_delete(struct priority_queue *pq)
{
    if (pq == NULL) return 0;

    int i, c;
    node last = pq->heap[pq->size--];

    for (i = 1; i * 2 <= pq->size; i = c) {
        c = i * 2;

        if (c < pq->size && pq->heap[c].priority > pq->heap[c+1].priority) c++;

        if (last.priority < pq->heap[c].priority) break;
        else pq_swap(pq, i, c);
    }

    pq->heap[i].priority = last.priority;
    pq->heap[i].val = last.val;

    return 1;
}
Example #9
0
void
pq_insert(PQ pq, const void *elt)
{
    int floater;                /* new element */

    while(pq->n + 1 > pq->size) {
        pq->size *= 2;
        pq->data = realloc(pq->data, pq->element_length * pq->size);
        assert(pq->data);
    }

    /* copy the new element in */
    floater = pq->n++;
    memcpy(REF(pq, floater), elt, pq->element_length);

    /* float it up until it is at the top */
    /* or it is no smaller than its parent */
    while(floater > 0 && pq->compare(REF(pq, floater), REF(pq, Parent(floater))) <= 0) {
        /* it's smaller than its parent */
        pq_swap(pq, floater, Parent(floater));
        floater = Parent(floater);
    }
}
Example #10
0
File: k9.c Project: hpersh/k9
static void
pq_erase(struct pq_node *nd)
{
  struct pq      *pq;
  unsigned       i, j, k;
  struct pq_node *parent, *left, *right;
  int            cl, cr;

  pq = nd->pq;

  if (pq == 0)  return;

  assert(pq->cnt > 0);

  if (--pq->cnt == 0)  return;

  pq_swap(pq, i = nd->idx, pq->cnt);

  for (;;) {
    parent = pq->arr[i];
    if ((j = (i << 1) + 1) >= pq->cnt) {
      /* No children */

      break;
    }
    left = pq->arr[j];
    cl = (*pq->cmp)(parent, left);
    if ((k = j + 1) >= pq->cnt) {
      /* Left child only */

      if (cl < 0) {
	/* Left child OK */

	break;
      }

      /* Left child not OK */
      goto swap_left;
    }

    /* 2 children */

    right = pq->arr[k];
    cr = (*pq->cmp)(parent, right);
    if (cl < 0) {
      /* Left child OK */

      if (cr < 0) {
	/* Right child OK */

	break;
      }

      /* Left child OK and right child not OK */

      goto swap_right;
    }

    /* Left child not OK */

    if (cr < 0) {
      /* Right child OK */

      goto swap_left;
    }

    /* Left child not OK and right child not OK */

    if ((*pq->cmp)(left, right))  goto swap_left;

  swap_right:
    pq_swap(pq, i, k);
    i = k;
    continue;

  swap_left:
    pq_swap(pq, i, j);
    i = j;
  }
}