Using qsort()

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.
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
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
Hmm... does line 7 of the example on that page give you a rough idea of what to do?

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

-Albatross
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.
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
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.
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
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.

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
&elem1 this gives you a pointer to a void pointer.
Oh, I can't believe i didn't change that. Thanks, Peter87!
Topic archived. No new replies allowed.