I need to stable sort an array with qsort. To ensure that the result is stable, I add one extra condition to the compare function:
int compare(const void *p1, const void *p2)
{
if(*(const Data*)p1 < *(const Data*)p2)
return -1;
if(*(const Data*)p2 < *(const Data*)p1)
return 1;
else
return p1<p2 ? -1 : 1;
}
This will work if qsort never calls compare(p,p). Otherwise I need to use a more complex condition. The question is, whether qsort ever calls compare() with a duplicate pointer or does it always compare different pointers?
UPDATE:
I checked this with Ideone C++ compiler: https://ideone.com/l026kM
For the small example { 8, 8, 1, 1 } in the comments, the provided implementation of qsort() does not change the order of pointers and does not call compare for the same element. This seems reasonable, because every reverse swap will affect performance, since it needs swapping back later on. I will test this with randomly generated arrays and different compilers.
UPDATE:
Tested on Ideone for 100000 random arrays with minimum 80% share of repetitive keys. The result is 100% stable sorted arrays. Here's the link: https://ideone.com/KOYbgJ
VC++Express 2008 compiler fails stable sort, because the order of the pointers is changed. This basically shows how VC++ implementation is different from GCC implementation in that it does not keep pointer order.