void exampleMinHeap() { // Use pooling for efficiency, if you don't want to use pooling // then comment out this line. pool_minheap(32); MinHeap* H = newMinHeap(31); minheap_add(H, 99, "99"); minheap_add(H, 45, "45"); minheap_add(H, 57, "57"); minheap_add(H, 12, "12"); minheap_add(H, 87, "87"); minheap_add(H, 42, "42"); minheap_add(H, 67, "67"); minheap_display(H, 2, &toString); printf("Pop: '%s'\n", (char*)minheap_popMin(H)); minheap_display(H, 2, &toString); printf("Pop: '%s'\n", (char*)minheap_popMin(H)); minheap_display(H, 2, &toString); printf("Update 45 to 91\n"); minheap_update(H, 45, 91); minheap_set(H, 91, "91"); minheap_display(H, 2, &toString); printf("Update 91 to 1\n"); minheap_update(H, 91, 1); minheap_set(H, 1, "1"); minheap_display(H, 2, &toString); printf("Add 50\n"); minheap_add(H, 50, "50"); minheap_display(H, 2, &toString); printf("Pop: '%s'\n", (char*)minheap_popMin(H)); minheap_display(H, 2, &toString); printf("Pop: '%s'\n", (char*)minheap_popMin(H)); printf("Pop: '%s'\n", (char*)minheap_popMin(H)); printf("Pop: '%s'\n", (char*)minheap_popMin(H)); printf("Pop: '%s'\n", (char*)minheap_popMin(H)); minheap_display(H, 2, &toString); minheap_clear(H); printf("\n"); // Build a much bigger heap int total = 21; int keys[] = {0, 23, 3, 6, 41, 17, 21, 8, 9, 68, 2, 1, 34, 29, 38, 11, 15, 16, 45, 65, 39}; char* items[] = {"0", "23", "3", "6", "41", "17", "21", "8", "9", "68", "2", "1", "34", "29", "38", "11", "15", "16", "45", "65", "39"}; while (--total >= 0) minheap_add(H, keys[total], items[total]); minheap_display(H, 2, &toString); printf("Popping.. "); while (!minheap_isEmpty(H)) printf("%s ", (char*)minheap_popMin(H)); printf("\n"); minheap_free(H); // If you're not using pooling this can be commented out. This will // free all pooled nodes from memory. Always call this at the end // of using any List. unpool_minheap(); }
/** To get the effective area, we have to check what area a point results in when all smaller areas are eliminated */ static void tune_areas(EFFECTIVE_AREAS *ea, int avoid_collaps, int set_area, double trshld) { LWDEBUG(2, "Entered tune_areas"); const double *P1; const double *P2; const double *P3; double area; int go_on=1; double check_order_min_area = 0; int npoints=ea->inpts->npoints; int i; int current, before_current, after_current; MINHEAP tree = initiate_minheap(npoints); int is3d = FLAGS_GET_Z(ea->inpts->flags); /*Add all keys (index in initial_arealist) into minheap array*/ for (i=0;i<npoints;i++) { tree.key_array[i]=ea->initial_arealist+i; LWDEBUGF(2, "add nr %d, with area %lf, and %lf",i,ea->initial_arealist[i].area, tree.key_array[i]->area ); } tree.usedSize=npoints; /*order the keys by area, small to big*/ qsort(tree.key_array, npoints, sizeof(void*), cmpfunc); /*We have to put references to our tree in our point-list*/ for (i=0;i<npoints;i++) { ((areanode*) tree.key_array[i])->treeindex=i; LWDEBUGF(4,"Check ordering qsort gives, area=%lf and belong to point %d",((areanode*) tree.key_array[i])->area, tree.key_array[i]-ea->initial_arealist); } /*Ok, now we have a minHeap, just need to keep it*/ /*for (i=0;i<npoints-1;i++)*/ i=0; while (go_on) { /*Get a reference to the point with the currently smallest effective area*/ current=minheap_pop(&tree, ea->initial_arealist)-ea->initial_arealist; /*We have found the smallest area. That is the resulting effective area for the "current" point*/ if (i<npoints-avoid_collaps) ea->res_arealist[current]=ea->initial_arealist[current].area; else ea->res_arealist[current]=FLT_MAX; if(ea->res_arealist[current]<check_order_min_area) lwerror("Oh no, this is a bug. For some reason the minHeap returned our points in the wrong order. Please file a ticket in PostGIS ticket system, or send a mial at the mailing list.Returned area = %lf, and last area = %lf",ea->res_arealist[current],check_order_min_area); check_order_min_area=ea->res_arealist[current]; /*The found smallest area point is now regarded as elimnated and we have to recalculate the area the adjacent (ignoring earlier elimnated points) points gives*/ /*FInd point before and after*/ before_current=ea->initial_arealist[current].prev; after_current=ea->initial_arealist[current].next; P2= (double*)getPoint_internal(ea->inpts, before_current); P3= (double*)getPoint_internal(ea->inpts, after_current); /*Check if point before current point is the first in the point array. */ if(before_current>0) { P1= (double*)getPoint_internal(ea->inpts, ea->initial_arealist[before_current].prev); if(is3d) area=triarea3d(P1, P2, P3); else area=triarea2d(P1, P2, P3); ea->initial_arealist[before_current].area = FP_MAX(area,ea->res_arealist[current]); minheap_update(&tree, ea->initial_arealist, ea->initial_arealist[before_current].treeindex); } if(after_current<npoints-1)/*Check if point after current point is the last in the point array. */ { P1=P2; P2=P3; P3= (double*)getPoint_internal(ea->inpts, ea->initial_arealist[after_current].next); if(is3d) area=triarea3d(P1, P2, P3); else area=triarea2d(P1, P2, P3); ea->initial_arealist[after_current].area = FP_MAX(area,ea->res_arealist[current]); minheap_update(&tree, ea->initial_arealist, ea->initial_arealist[after_current].treeindex); } /*rearrange the nodes so the eliminated point will be ingored on the next run*/ ea->initial_arealist[before_current].next = ea->initial_arealist[current].next; ea->initial_arealist[after_current].prev = ea->initial_arealist[current].prev; /*Check if we are finnished*/ if((!set_area && ea->res_arealist[current]>trshld) || (ea->initial_arealist[0].next==(npoints-1))) go_on=0; i++; }; destroy_minheap(tree); return; }