Open In App

Comparator function of qsort() in C

Improve
Improve
Like Article
Like
Save
Share
Report

Standard C library provides qsort() that can be used for sorting an array. As the name suggests, the function uses QuickSort algorithm to sort the given array. Following is the prototype of qsort()

void qsort (void* base, size_t num, size_t size, 
           int (*comparator)(const void*,const void*));

Comparator Function in qsort()

The key point about qsort() is the comparator() function. The comparator function takes two arguments and contains logic to decide their relative order in the sorted output. The idea is to provide flexibility so that qsort() can be used for any type (including user-defined types) and can be used to obtain any desired order (increasing, decreasing, or any other).

The comparator function takes two pointers as arguments (both type-casted to const void*) and defines the order of the elements by returning (in a stable and transitive manner

Prototype of comparator() function

int comparator(const void* p1, const void* p2);

Parameters

  • p1 and p2: These are the pointer to the elements to be compared.

Return Value

The comparator function should only return the following values:

  • ( <0 ): Less than zero, if the element pointed by p1 goes before the element pointed by p2.
  • ( 0 ): Zero, if the element pointed by p1 is equivalent to the element pointed by p2.
  • ( >0 ): Greater than zero, if the element pointed by p1 goes after the element pointed by p2.

For example, let there be an array of struct of students where the following is the type of student element.

struct Student
{
   int age, marks;
   char name[20];
};

We need to sort the students based on marks in ascending order. The comparator function will look like this:

int comparator(const void* p, const void* q)
{
   int l = ((struct Student*)p)->marks;
   int r = ((struct Student*)q)->marks;
   return (l - r);
}

Example

The following is an interesting problem that can be easily solved with the help of qsort() and comparator() functions.

Problem Statement:

Given an array of integers, sort it in such a way that the odd numbers appear first and the even numbers appear later. The odd numbers should be sorted in descending order and the even numbers should be sorted in ascending order.

Simple Approach:

The simple approach is to first modify the input array such that the even and odd numbers are segregated followed by applying some sorting algorithm on both parts(odd and even) separately.

However, there exists an interesting approach with a little modification in the comparator() function of Quick Sort.

Better Approach:

The idea is to write a comparator function that takes two addresses p and q as arguments. Let l and r be the number pointed by p and q.

  • If both (l and r) are odd, put the greater of two first.
  • If both (l and r) are even, put the smaller of the two first.
  • If one of them is even and the other is odd, put the odd number first.

Below is the implementation of the above approach:

C




// C program to illustrate the use of comparator function in
// qsort()
#include <stdio.h>
#include <stdlib.h>
  
// This function is used in qsort to decide the relative
// order of elements at addresses p and q.
int comparator(const void* p, const void* q)
{
    // Get the values at given addresses
    int l = *(const int*)p;
    int r = *(const int*)q;
  
    // both odd, put the greater of two first.
    if ((l & 1) && (r & 1))
        return (r - l);
  
    // both even, put the smaller of two first
    if (!(l & 1) && !(r & 1))
        return (l - r);
  
    // l is even, put r first
    if (!(l & 1))
        return 1;
  
    // l is odd, put l first
    return -1;
}
  
// A utility function to print an array
void printArr(int arr[], int n)
{
    int i;
    for (i = 0; i < n; ++i)
        printf("%d ", arr[i]);
}
  
// Driver program to test above function
int main()
{
    int arr[] = { 1, 6, 5, 2, 3, 9, 4, 7, 8 };
  
    int size = sizeof(arr) / sizeof(arr[0]);
    qsort((void*)arr, size, sizeof(arr[0]), comparator);
  
    printf("Output array is\n");
    printArr(arr, size);
  
    return 0;
}


Output

Output array is
9 7 5 3 1 2 4 6 8 

See the following posts for more sample uses of qsort().

Exercise: Given an array of integers, sort it in alternate fashion. Alternate fashion means that the elements at even indices are sorted separately and elements at odd indices are sorted separately.

This article is compiled by Aashish Barnwal.



Last Updated : 11 Sep, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads