qsort()

This topic is 4684 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I'm trying to sort an array of units in the following way: -Find the unit in the middle -sort the units from closest (to the middle unit) to furthest. I used
middle_man = FindMiddle();
qsort((void *) &unit, number_of_units, sizeof(struct unit), (compfn)CompareDisMid );


were the FindMiddle function finds the place in the array of the middle unit. That part works. For the compare I used:
int CompareDisMid(struct unit *elem1, struct unit *elem2)
{
if(abs(elem1->current_step.x-unit[middle_man].current_step.x)+
abs(elem1->current_step.y-unit[middle_man].current_step.y)
<abs(elem2->current_step.x-unit[middle_man].current_step.x)+
abs(elem2->current_step.y-unit[middle_man].current_step.y))
return -1;
else if(abs(elem1->current_step.x-unit[middle_man].current_step.x)+
abs(elem1->current_step.y-unit[middle_man].current_step.y)
>  abs(elem2->current_step.x-unit[middle_man].current_step.x)+
abs(elem2->current_step.y-unit[middle_man].current_step.y))
return 1;
else											 return 0;

}


The problem is that it takes 2-3 time of calling qsort for it to work properly. For example, the middle_man should turn to 0 after one call right?! What is the problem? I think that the problem could be connected to the fact that during the qsort the middle_man changes. If so how do I fix it? Thanks a lot

Share on other sites
Indeed, your sort is going to change the value of unit[middle_man] is going to change over the course of your sort.

I can think of two ways around it. The first would involve copying your middle object rather than repeatedly checking the actual unit array. This has the added advantage of removing the dependancy on your unit array from your comparison function. The other would involve swapping unit[middle_man] with unit[0], and only sorting from unit[1] on. Or do both.

CM

Share on other sites
In other words, do this:
struct unit middle_man = unit[FindMiddle()]; // Copy the middle man     qsort((void *) &unit, number_of_units, sizeof(struct unit), (compfn)CompareDisMid );int CompareDisMid(struct unit *elem1, struct unit *elem2){   if(abs(elem1->current_step.x-middle_man.current_step.x)+      abs(elem1->current_step.y-middle_man.current_step.y)     <abs(elem2->current_step.x-middle_man.current_step.x)+      abs(elem2->current_step.y-middle_man.current_step.y))      return -1;   else if(abs(elem1->current_step.x-middle_man.current_step.x)+           abs(elem1->current_step.y-middle_man.current_step.y)        >  abs(elem2->current_step.x-middle_man.current_step.x)+           abs(elem2->current_step.y-middle_man.current_step.y))      return 1;   else      return 0;}
You could of course do even better by just copying the current_step member of the struct, rather than the whole thing, but I don't know what type it is, so I'll leave that as an exersize for you.

Though I think you've written this example code as if 'unit' were both a type and your array name.

Share on other sites
Thanks it worked!!

1. 1
2. 2
3. 3
4. 4
5. 5
Rutin
15

• 14
• 9
• 10
• 12
• 17
• Forum Statistics

• Total Topics
632910
• Total Posts
3009177
• Who's Online (See full list)

There are no registered users currently online

×