Ejemplo n.º 1
0
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();
}
Ejemplo n.º 2
0
/**

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;	
}