I have read that the comparison function required by qsort()
needs to have 3 outcomes:
val1 < val2
0
if val1 == val2
val1 > val2
As far as I know, sorting an array only requires a predicate that returns true or false. Take bubble sort for example:
int compare(int a, int b)
{
if(a>b) return 1;
return 0;
}
void bubbleSort(int arr[], int n)
{
int i, j;
for (i = 0; i < n-1; i++)
for (j = 0; j < n-i-1; j++)
if ( compare(arr[j],arr[j+1]) )
swap(&arr[j], &arr[j+1]);
}
So why does the qsort()
comparison function need to have 3 possible outcomes and not 2?
The compare pointer points to a function, which you supply, that compares two array elements and returns an integer value specifying their relationship. The qsort() function calls the comparison function one or more times during the sort, passing pointers to two array elements on each call.
The qsort() function sorts the given array pointed by base in ascending order. The array contains num elements, each of size bytes. The function pointed by compare is used to compare two elements of the array. This function modifies the content of the array itself in the ascending order.
In the C Programming Language, the strcmp function returns a negative, zero, or positive integer depending on whether the object pointed to by s1 is less than, equal to, or greater than the object pointed to by s2.
The qsort() function calls this function by the pointer passed in the last argument to qsort() each time it needs to compare two elements of the array. The comparison function takes as its arguments two pointers to elements of the array being sorted.
qsort
could be written using a boolean compare function instead of a three-way compare but the specification says that it takes a three-way compare function and some (not all) implementations take advantage of the three possible cases. If your compare function doesn't conform to the specification, Undefined Behaviour will result. In this case, Undefined Behaviour might include a failure to sort correctly or a buffer overrun triggered on very rare corner cases, which you might not notice until the space shuttle is returning from orbit. So don't do that.
As to why an implementation might want the three-way comparison, here is one possibility: for inputs with a lot of repeated values, quicksort can be speeded up considerably by using a three-way partition. That can be done with a two-way comparison by doing the comparison twice in opposite directions, but an implementor, knowing that a three-way comparator is required, is likely to test for equality when that's what they want to know.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With