# Comparator function of qsort() in C

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 prototype of qsort()

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

*chevron_right*

*filter_none*

The key point about qsort() is comparator function *comparator*. The comparator function takes two arguments and contains logic to decide their relative order in 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

int comparator(const void* p1, const void* p2); Return value meaning <0 The element pointed by p1 goes before the element pointed by p2 0 The element pointed by p1 is equivalent to the element pointed by p2 >0 The element pointed by p1 goes after the element pointed by p2 Source: http://www.cplusplus.com/reference/cstdlib/qsort/

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

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

*chevron_right*

*filter_none*

Lets say we need to sort the students based on marks in ascending order. The comparator function will look like:

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

*chevron_right*

*filter_none*

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

Given a sequence of words, print all anagrams together

Box Stacking Problem

Closest Pair of Points

Following is an interesting problem that can be easily solved with the help of *qsort()* and comparator function.

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

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 comparator function of Quick Sort. 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. The function uses following logic:

1) If both (l and r) are odd, put the greater of two first.

2) If both (l and r) are even, put the smaller of two first.

3) If one of them is even and other is odd, put the odd number first.

Following is C implementation of the above approach.

`#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; ` `} ` |

*chevron_right*

*filter_none*

Output:

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

**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. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

## Recommended Posts:

- C qsort() vs C++ sort()
- Sort an array of pairs using Java Pair and Comparator
- Function Overloading vs Function Overriding in C++
- What happens when a virtual function is called inside a non-virtual function in C++
- div() function in C++
- log() function in C++
- exp() function C++
- fma() function in C++
- arc function in C
- c16rtomb() function in C/C++
- mbrtowc() function in C/C++
- wcsrchr() function in C/C++
- wcspbrk() function in C/C++
- mbrlen() function in C/C++
- strrchr() function in C/C++