/**Function************************************************************* Synopsis [Moves the entry up.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Msat_HeapPercolateUp( Msat_Order_t * p, int i ) { int x = HHEAP(p, i); while ( HPARENT(i) != 0 && HCOMPARE(p, x, HHEAP(p, HPARENT(i))) ) { p->vHeap->pArray[i] = HHEAP(p, HPARENT(i)); p->vIndex->pArray[HHEAP(p, i)] = i; i = HPARENT(i); } p->vHeap->pArray[i] = x; p->vIndex->pArray[x] = i; }
/* move an element suitably so it is in a correct place */ static inline void adjustheap (ANHE *heap, int N, int k) { if (k > HEAP0 && heap[k].at <= heap[HPARENT(k)].at ) upheap (heap, k); else downheap (heap, N, k); }
/* * Returns the index into the heap array */ int heapInsert(HEAP heap,const DSKEY key,void *data) { Heap * h = (Heap*)heap; HeapElement * he; int i,pidx; HeapInternCmp cmp_func; DBG(debug("heapInsert(heap=%p,key=%p,data=%p)\n", heap,key,data)); if (!h) { XLOG(h); return -1; } if (h->hpMode == HEAP_MINIMIZE) cmp_func = heap_larger; else cmp_func = heap_smaller; /* 1. Make a new element */ he = heap_new_element(key,data); /* 2. Grow the heap if needed */ if (NEEDS2GROW(h) && heap_grow(h)) { LLOG(-1); return -1; } /* 3. Insert the new element into the heap */ i = HSIZE(h); pidx = HPARENT(i); while (i > 0 && cmp_func(h,HARRAY(h,pidx),he)) { if (h->hpChgFunc) h->hpChgFunc(HARRAY(h,pidx)->heData,i); HARRAY(h,i) = HARRAY(h,pidx); i = pidx; pidx = HPARENT(i); } HARRAY(h,i) = he; HSIZE(h)++; return i; }
/* towards the root */ static inline void upheap (ANHE *heap, int k){ ANHE he = heap [k]; for (;;) { int p = HPARENT (k); //he has no parent or he is later than parent if (UPHEAP_DONE(p, k) || heap[p].at <= he.at) break; heap[k] = heap[p]; heap[k].w->active = k; k = p; } heap[k] = he; he.w->active = k; }
/* * Return an element from the heap, located at the given index */ static HeapElement * heap_delete(Heap * h,int idx) { HeapElement *he,*helast; int pidx; HeapInternCmp cmp_func; DBG(debug("heap_delete(h=%p,idx=%d)\n",h,idx)); LLOG(HSIZE(h)); if (idx < 0 || idx >= HSIZE(h)) { LLOG(idx); return NULL; } if (h->hpMode == HEAP_MAXIMIZE) cmp_func = heap_larger; else cmp_func = heap_smaller; /* Remember the current element */ he = HARRAY(h,idx); /* Remember the last element */ helast = HLAST(h); h->hpFilled--; if (idx == HSIZE(h)) /* This is the last element */ goto end_label; /* Put the last element in the position of the current */ HARRAY(h,idx) = helast; if (h->hpChgFunc) h->hpChgFunc(HARRAY(h,idx)->heData,idx); /* Heapify the new subtree. Then if the root of the subtree * is larger than its parent, propagate it up the tree until * it finds is proper location */ heap_heapify(h,idx); pidx = HPARENT(idx); LLOG(pidx); if (idx > 0) { while (cmp_func(h,HARRAY(h,idx),HARRAY(h,pidx))) { heap_swap(h,idx,pidx); idx = pidx; if (idx == 0) break; pidx = HPARENT(idx); } } end_label: if (NEEDS2SHRINK(h)) heap_shrink(h); return he; }
/**Function************************************************************* Synopsis [Checks the heap property recursively.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Msat_HeapCheck_rec( Msat_Order_t * p, int i ) { return i >= HSIZE(p) || ( HPARENT(i) == 0 || !HCOMPARE(p, HHEAP(p, i), HHEAP(p, HPARENT(i))) ) && Msat_HeapCheck_rec( p, HLEFT(i) ) && Msat_HeapCheck_rec( p, HRIGHT(i) ); }