Quick sort, usually written as quicksort, is a divide-and-conquer sorting algorithm: it selects a pivot, partitions an array around that value, then recursively sorts the resulting subranges. A hand-written version gives you control over those steps; C’s qsort() library function provides a general sorting interface, but the C and POSIX specifications do not require it to use quicksort internally.
How quicksort sorts an array
Quicksort works on a range of elements. It chooses one element as a pivot, rearranges the range so values that compare lower are on one side and higher values are on the other, and places the pivot in its final sorted position. It then applies the same process to the two ranges on either side. The process stops when a range has zero or one element, since such a range is already sorted. MIT’s 6.087 Practical Programming in C lecture presents this recursive structure and relates it to C’s qsort() facility: MIT 6.087 lecture material.
| # | Preview | Product | Price | |
|---|---|---|---|---|
| 1 |
|
Introduction to Algorithms, fourth edition | $91.50 | Buy on Amazon |
| 2 |
|
Algorithms (4th Edition) | $68.77 | Buy on Amazon |
| 3 |
|
Algorithm Design | $224.59 | Buy on Amazon |
| 4 |
|
Introduction to Algorithms, 3rd Edition | $99.94 | Buy on Amazon |
| 5 |
|
The Algorithm Design Manual (Texts in Computer Science) | $48.57 | Buy on Amazon |
For example, partitioning [8, 3, 6, 2] around pivot 2 places 2 before the larger values. The algorithm then sorts the remaining range. The exact intermediate order depends on the pivot and partition method.
A simple recursive quicksort in C
This teaching example sorts integers in place. Its range endpoints are inclusive, so call it with lo = 0 and hi = count - 1 for a nonempty array.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
- color: White
- INTRODUCTION TO ALGORITHMS, FOURTH EDITION
#include <stddef.h>
static void swap_int(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
static int partition(int a[], int lo, int hi) {
int pivot = a[hi];
int i = lo;
for (int j = lo; j < hi; ++j) {
if (a[j] <= pivot) {
swap_int(&a[i], &a[j]);
++i;
}
}
swap_int(&a[i], &a[hi]);
return i;
}
void quicksort_int(int a[], int lo, int hi) {
if (lo >= hi) return;
int p = partition(a, lo, hi);
quicksort_int(a, lo, p - 1);
quicksort_int(a, p + 1, hi);
}
What the partition function guarantees
Before each loop iteration, elements in the processed portion that compare less than or equal to the pivot are kept to the left; the remaining processed elements are greater. At the end, the pivot is swapped into index i. The function returns that index, so the recursive calls exclude the pivot itself.
Calling it safely
For an array with count elements, avoid computing count - 1 when the array is empty. One straightforward call-site check is:
Rank #2
if (count > 0) {
quicksort_int(values, 0, count - 1);
}
This implementation is intentionally basic: it always selects the last element as pivot. That makes the code easy to follow, but input patterns and many duplicate values can lead to highly unbalanced partitions and deep recursion. For production use, consider pivot strategy, recursion depth, duplicate-heavy or adversarial inputs, and whether the library routine better suits the requirement.
How fast is quicksort?
When partitions are reasonably balanced, quicksort’s average running time is O(n log n). When each pivot leaves one large subrange and one tiny subrange, the worst case is O(n²). These are properties of the algorithm; they are not performance guarantees for the C qsort() interface. A detailed analysis of quicksort reports these bounds: arXiv, “A Detailed Analysis of Quicksort Running Time”.
Rank #3
How to use C’s qsort()
For general-purpose sorting, C provides qsort() through <stdlib.h>. You supply the array’s base address, the number of elements, each element’s size in bytes, and a comparator.
#include <stdlib.h>
static int cmp_int(const void *pa, const void *pb) {
int a = *(const int *)pa;
int b = *(const int *)pb;
return (a > b) - (a < b);
}
/* Sort count integers in values. */
qsort(values, count, sizeof values[0], cmp_int);
The comparator returns a negative value when the first element should come before the second, zero when they compare equal, and a positive value when the first should come after the second. It must provide consistent ordering and must not modify the array. The Open Group specifies the array-sorting interface in its POSIX qsort() reference; Microsoft also documents its C runtime comparator interface at Microsoft Learn: qsort.
Rank #4
- Hard Cover
Hand-written quicksort or qsort()?
| Consideration | Hand-written quicksort | qsort() |
|---|---|---|
| Control | You choose pivot handling, partitioning, data type, and recursion safeguards. | You provide an element comparator; internal sorting strategy is implementation-defined and not specified by the interface. |
| Types and comparison | A specialized integer function can compare values directly. | The comparator receives generic pointers and must interpret the element type. |
| Performance claims | The usual quicksort average and worst-case bounds apply to the algorithm and its pivot behavior. | C and POSIX do not promise a complexity bound; avoid claiming it is quicksort unless you have verified the specific library and version. |
| Equal elements | Stability depends on how your implementation is written. | Equal elements have unspecified relative order; qsort() is not a stable-sort interface. |
| Portability | Your implementation and its assumptions are your responsibility. | The standard C sorting interface is portable, though implementation details and performance can differ. |
For a portable comparator-based sort, qsort() is often the direct choice. Write a custom algorithm when you need specific control, are learning partitioning, or have requirements the library interface does not address. If equal elements must retain their original order, neither the name nor interface of qsort() provides that guarantee.
Is qsort() actually quicksort?
Not necessarily. The name is historical, not a promise about the algorithm used by every C library. POSIX specifies what the function must do—“The qsort() function shall sort an array of nel objects”—but not which sorting algorithm it must use. Microsoft’s C runtime documentation says its qsort function implements a quick-sort algorithm, but that is a statement about Microsoft’s implementation, not a universal C guarantee. See the Open Group specification and Microsoft documentation.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Quick Recap
Best Value
Common mistakes to avoid
- Using a subtraction comparator: returning
*(int *)pa - *(int *)pbcan overflow for extreme integer values. The relational comparison pattern in the example avoids that subtraction. - Getting the recursive ranges wrong: once partition returns
p, recurse onlo..p-1andp+1..hi, not on ranges that include the pivot again. - Assuming stability:
qsort()does not specify the relative order of equal elements. - Assuming the library’s name guarantees its internals: the standard interface does not promise quicksort, a time bound, or a particular pivot policy.
- Ignoring the empty-array case: guard the call before forming an inclusive upper index such as
count - 1.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

