Comparator function of qsort() in C



In C, sorting arrays is a common task, and one of the functions that help with sorting is qsort(). To sort the array, qsort() needs a comparator function to decide how to compare two elements. Without this function, qsort() wouldn't know how to order the data.

The task here is to understand how to write and use a comparator function with qsort() to sort arrays in different orders.

For example, consider this array of integers:

arr[] = {5, 2, 9, 1, 5, 6}

We want to sort this array in ascending or descending order. The comparator function tells qsort() how to compare two numbers, and based on that, it will perform the necessary swaps to sort the array as shown below ?

Input: arr[] = {5, 2, 9, 1, 5, 6}

Output (Ascending Order): arr[] = {1, 2, 5, 5, 6, 9}
Output (Descending Order): arr[] = {9, 6, 5, 5, 2, 1}

In this article, we will show how to use the qsort() function in C and write the comparator function for different sorting methods.

Rules for Defining Comparator Function

To write a valid comparator function for qsort(), there are a few important rules to follow:

  • Return Type: The comparator function must return an integer. However, it may also return other values. If the first element is smaller than the second, it returns a -ve value. It returns Zero when both elements are equal and a +ve value if the first element is greater than the second.
  • Parameters: The function receives two arguments, both of type const void *. This is because qsort() is designed to work with arrays of any data type, so the comparator function must handle the data type appropriately. Inside the comparator function, you need to cast the pointers to the correct data type (e.g., int *, float *, or struct *) before accessing the values.
  • Data Types: The comparator function can handle any data type, from primitive types like int, char, float, to more complex data types like struct.

How to use Comparator Functions?

We will cover different ways to use a comparator function for:

Comparator Function for Ascending Order

In this approach, we write a simple comparator function to sort an array in ascending order. The function compares two elements and returns:

  • A negative value if the first element is smaller.
  • Zero if the elements are equal.
  • A positive value if the first element is larger.

Example

We write a comparator function to compare two integers, then use qsort() to sort an array of integers in ascending order.

#include <stdio.h>
#include <stdlib.h>

// Comparator function for ascending order
int compareAsc(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);  // Compare integers for ascending order
}

int main() {
    int arr[] = {5, 2, 9, 1, 5, 6};
    int size = sizeof(arr) / sizeof(arr[0]);

    // Display the original array
    printf("Original array: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    // Sorting the array in ascending order
    qsort(arr, size, sizeof(int), compareAsc);

    // Display the sorted array
    printf("Sorted array (ascending): ");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

The output displays the array sorted in ascending order.

Original array: 5 2 9 1 5 6 
Sorted array (ascending): 1 2 5 5 6 9 

Time Complexity: O(n log n)

Space Complexity O(n)

Comparator Function for Descending Order

In this approach, we modify the comparator function to sort the array in descending order. The logic remains similar, but this time we reverse the comparison to ensure the larger elements come before the smaller ones.

Example

Here, we create a comparator for descending order and pass it to qsort() to sort the array in reverse order.

#include <stdio.h>
#include <stdlib.h>

// Comparator function for descending order
int compareDesc(const void *a, const void *b) {
    return (*(int*)b - *(int*)a);  // Reverse comparison for descending order
}

int main() {
    int arr[] = {5, 2, 9, 1, 5, 6};
    int size = sizeof(arr) / sizeof(arr[0]);

    // Display the unsorted (original) array
    printf("Unsorted array: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    // Sorting the array in descending order
    qsort(arr, size, sizeof(int), compareDesc);

    // Display the sorted array in descending order
    printf("Sorted array (descending): ");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    return 0;
}

The output will show the array sorted in descending order.

Unsorted array: 5 2 9 1 5 6 
Sorted array (descending): 9 6 5 5 2 1

Time Complexity: O(n log n)

Space Complexity: O(n)

Custom Sorting

In this approach, we use custom sorting, like sorting an array of structures. Each structure may contain multiple fields, and we need to specify which field to use for sorting. We write a comparator function based on a field (e.g., age, name, etc.) inside the struct.

Example

Here, we define a structure Person with fields name and age, and write a comparator function that sorts people by their age in ascending order.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Structure to store person details
typedef struct {
    char name[50];
    int age;
} Person;

// Comparator function for sorting by age
int compareAge(const void *a, const void *b) {
    return ((*(Person*)a).age - (*(Person*)b).age);  // Compare by age
}

int main() {
    Person people[] = {
        {"Alice", 25},
        {"Bob", 30},
        {"Charlie", 20},
        {"Dave", 35}
    };
    int size = sizeof(people) / sizeof(people[0]);

    // Display the unsorted (original) array of people
    printf("Unsorted array of people: \n");
    for (int i = 0; i < size; i++) {
        printf("%s, %d\n", people[i].name, people[i].age);
    }
    printf("\n");

    // Sorting by age
    qsort(people, size, sizeof(Person), compareAge);

    // Display the sorted array of people
    printf("Sorted array by age: \n");
    for (int i = 0; i < size; i++) {
        printf("%s, %d\n", people[i].name, people[i].age);
    }
   return 0;
}

The output displays the array of structures sorted by age.

Unsorted array of people: 
Alice, 25
Bob, 30
Charlie, 20
Dave, 35

Sorted array by age: 
Charlie, 20
Alice, 25
Bob, 30
Dave, 35

Time Complexity: O(n log n)

Space Complexity: O(n)

Conclusion

In this article, we explained the qsort() function in C and how to use custom comparators for sorting. We covered sorting in ascending and descending order, as well as sorting structures. Understanding comparators is key to using qsort() effectively.

Updated on: 2025-02-14T18:09:25+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements