Using qsort()

Mar 5, 2012 at 3:12pm
I'm currently trying to sort an array of type cable, which is a class.
1
2
3
4
5
class Cable
{
public:
	int city1,city2, cost;
};


How would i sort this array using qsort(), with length ncables, based on the cost element of the array.
Mar 5, 2012 at 3:16pm
Wait, if you're using C++, why are you using qsort() when you can use std::sort()?

You'll probably want to write a function that takes two Cables, gets the costs from them, and return the order in which they (the elements) should go in the form of a boolean. std::sort() can take a function to replace the < operator (if it exists).
http://cplusplus.com/reference/algorithm/sort/

Good luck!

-Albatross
Last edited on Mar 5, 2012 at 7:29pm
Mar 5, 2012 at 3:21pm
Thanks for this. It doesn't really matter what i use, but i'm having trouble constructing the comparator, and would like some guidance on building that
Mar 5, 2012 at 3:24pm
Hmm... does line 7 of the example on that page give you a rough idea of what to do?

-Albatross
Mar 5, 2012 at 3:26pm
it does, but how would i specify that i want it to sort the array based on the cost element?
Mar 5, 2012 at 3:56pm
Since your cost element is public, then can't you just use the . operator to get it from your objects and compare that?

-Albatross
Mar 5, 2012 at 6:04pm
I'm just having trouble implementing it. For the comparator, it needs to follow int comparator ( const void * elem1, const void * elem2 );

I just don't know how to construct this to take the .cost element.
Mar 5, 2012 at 6:09pm
If you are using qsort you need to cast the pointers to the correct type before you can access the class members.

It's much easier to use std::sort, you don't need to cast. Just define the comparator
bool comparator ( const Cable& elem1, const Cable& elem2 );
Last edited on Mar 5, 2012 at 6:09pm
Mar 5, 2012 at 6:45pm
Ok, so i've tried to cast the pointers and all and use quicksort.

1
2
3
4
5
6
7
int comparator ( const void * elem1, const void * elem2 )
{
	Cable* c1= (Cable*) &elem1;
	Cable* c2= (Cable*) &elem2;
	if(c1->cost > c2->cost) return 1;
	else return 0;
}


I've got this as the comparator, using qsort(cables,ncables, sizeof(Cable), comparator);

The problem is that it just seems to not sort all of these in any specific order at all, it just changes them around.
Mar 5, 2012 at 6:51pm
For simplicity's sake perhaps just use references to Cable objects?

1
2
3
4
int maxCable( const Cable &c1, const Cable &c2)
{
  return (c1.cost < c2.cost) ? -1 : ((c1.cost > c2.cost) ? 1 : 0);
}


EDIT: After Peter87's explanation, reworked the return
Last edited on Mar 5, 2012 at 7:27pm
Mar 5, 2012 at 7:17pm
The problem is that the qsort comparator should return a negative number if elem1 is less than elem2, zero if both elements are equal and a positive number if elem1 is greater than elem2.

Mar 5, 2012 at 7:48pm
Texan40, with qsort, the comparator has to be int comparator(const void *, const void *)

If it was just a regular comparator i'd be fine, but i can't seem to get this one to work.

I've currently got
1
2
3
4
5
6
7
8
int comparator ( const void * elem1, const void * elem2 )
{
	Cable* c1= (Cable*) &elem1;
	Cable* c2= (Cable*) &elem2;
	if(c1->cost < c2->cost) return -1;
	else if(c1->cost > c2->cost) return 1;
	else return 0;
}


and
qsort(cables,ncables, sizeof(Cable), comparator);
Last edited on Mar 5, 2012 at 7:48pm
Mar 5, 2012 at 8:22pm
&elem1 this gives you a pointer to a void pointer.
Mar 5, 2012 at 8:29pm
Oh, I can't believe i didn't change that. Thanks, Peter87!
Topic archived. No new replies allowed.