static int check_values(Heap *h,int idx,int depth) { HeapElement *he_l = NULL; HeapElement *he_r = NULL; HeapElement *he_p = NULL; HeapInternCmp cmp_func; if (idx < 0 || idx >= HSIZE(h)) return 0; if (h->hpMode == HEAP_MINIMIZE) cmp_func = heap_larger; else cmp_func = heap_smaller; he_p = HARRAY(h,idx); if (HLEFT(idx) >= HSIZE(h)) /* No left child */ return 0; if (HRIGHT(idx) < HSIZE(h)) /* Has right child */ he_r = HARRAY(h,HRIGHT(idx)); he_l = HARRAY(h,HLEFT(idx)); if ( cmp_func(h,he_p,he_l)) { printf("*** Heap violates parent-lchild property.\n"); printf("*** Left child (%d) is %s than parent (%d)\n", HLEFT(idx), h->hpMode == HEAP_MINIMIZE ? "smaller" : "larger", idx); printf("*** Depth %d\n",depth); printf("%.8f - %.8f = %.8f\n",Key2Double(he_l),Key2Double(he_p), Key2Double(he_l) - Key2Double(he_p)); return -1; } if (he_r && cmp_func(h,he_p,he_r)) { printf("*** Heap violates parent-rchild property.\n"); printf("*** Right child (%d) is %s than parent (%d)\n", HRIGHT(idx),h->hpMode == HEAP_MINIMIZE ? "smaller" : "larger", idx); printf("*** Depth %d\n",depth); printf("%.8f - %.8f = %.8f\n",Key2Double(he_r),Key2Double(he_p), Key2Double(he_r) - Key2Double(he_p)); return -1; } if (check_values(h,HLEFT(idx),depth+1)) return -1; if (he_r) return check_values(h,HRIGHT(idx),depth+1); return 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; }
void* heapElementAt(HEAP heap,int idx) { Heap * h = (Heap*)heap; DBG(debug("heapElementAt(heap=%p,idx=%d)\n",heap,idx)); if (!h) { XLOG(h); return NULL; } if (idx < 0 || idx >= HSIZE(h)) { LLOG(idx); LLOG(HSIZE(h)); return NULL; } return HARRAY(h,idx)->heData; }
/**Function************************************************************* Synopsis [Inserts the new element.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Msat_HeapInsert( Msat_Order_t * p, int n ) { assert( HOKAY(p, n) ); p->vIndex->pArray[n] = HSIZE(p); Msat_IntVecPush( p->vHeap, n ); Msat_HeapPercolateUp( p, p->vIndex->pArray[n] ); }
/* * 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; }
void heapPrintTree(HEAP heap,HEAPPRINTFUNC printfunc) { Heap *h = (Heap*)heap; if (HSIZE(h) == 0) { XLOG(0); return; } print_tree(h,0,0,printfunc); }
/**Function************************************************************* Synopsis [Moves the entry down.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Msat_HeapPercolateDown( Msat_Order_t * p, int i ) { int x = HHEAP(p, i); int Child; while ( HLEFT(i) < HSIZE(p) ) { if ( HRIGHT(i) < HSIZE(p) && HCOMPARE(p, HHEAP(p, HRIGHT(i)), HHEAP(p, HLEFT(i))) ) Child = HRIGHT(i); else Child = HLEFT(i); if ( !HCOMPARE(p, HHEAP(p, Child), x) ) break; p->vHeap->pArray[i] = HHEAP(p, Child); p->vIndex->pArray[HHEAP(p, i)] = i; i = Child; } p->vHeap->pArray[i] = x; p->vIndex->pArray[x] = i; }
/* * Print routines, can be useful.... */ void heapPrintArray(HEAP heap,HEAPPRINTFUNC printfunc) { Heap *h = (Heap*)heap; int i; for (i = 0; i < HSIZE(h); i++) { HeapElement * he = HARRAY(h,i); printfunc(-1,he->heKey,he->heData); } printf("\n"); }
static void heap_walk(Heap *h,int idx,int depth,HEAPWALKFUNC func) { HeapElement *he; if (idx < 0 || idx >= HSIZE(h)) return; he = HARRAY(h,idx); func(depth,he->heKey,he->heData); heap_walk(h,HLEFT(idx),depth + 1,func); heap_walk(h,HRIGHT(idx),depth + 1,func); }
static void print_tree(Heap * h,int idx,int depth, HEAPPRINTFUNC func) { HeapElement *he; DBG(debug("print_tree(h=%p,idx=%d,depth=%d,func=%p)\n", h,idx,depth,func)); if (idx < 0 || idx >= HSIZE(h)) return; he = HARRAY(h,idx); func(depth,he->heKey,he->heData); print_tree(h,HLEFT(idx),depth+1,func); print_tree(h,HRIGHT(idx),depth+1,func); }
/* * 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) ); }