Quick Sort
Contents
14.4. Quick Sort#
The last sorting algorithm we discuss is quicksort. It is an efficient sorting algorithm that works on the principle of divide-and-conquer. The algorithm divides the array into two sub-arrays, and then recursively sorts (conquers) the sub-arrays. It is “quick” for large arrays compared to other sorting algorithms.
14.4.1. Algorithm#
The general idea of quicksort is based on the observation that if for an element in an array, all the elements to the left of it are smaller than it, and all the elements to the right of it are larger than it, then the element is in its correct position. We call this element the “pivot”. This is even if the elements on the right or left are not sorted. For example, in the following figure, 10 is a pivot.

The basic idea of quicksort is to pick a number and call it a pivot. This requires rearranging the array such that all elements on the left of the pivot are smaller than it, and all elements on the right of the pivot are larger than it. This is called the partitioning process.
The elements to the left of the pivot is considered a “left sub-array”, and the elements on the right are “right sub-array”. The partitioning process is then done recursively for the left and right sub-arrays. This happens until the sub-arrays are of size 1, which means they are sorted.
Given the following example array named int A[] = {9, 5, 18, 8, 5, 2};
,

the algorithm works as follows:
Pick a pivot element from the array that we will place in its correct position. We can pick the first element. Then, we can start from index
left = 1
andright = 8
. We will incrementleft++
until we find an element that is smaller than the pivot onA[left]
, and decrementright--
until we find an element atA[right]
that is larger than the pivot. In the following example,left
stops at1
andright
stops at8
.We then swap
A[left]
andA[right]
. This brings the smaller element to the left and the larger element to the right.We increment
left
tillA[left] > pivot
and decrementright
tillA[right] < pivot
. In the following example,left
stops at3
andright
stops at7
, and we swapA[left]
andA[right]
.We repeat this process and notice elements smaller than the pivot are populating the left and greater than pivot populating the right.
left
stops at4
andright
stops at6
, and we swapA[left]
andA[right]
.We continue this process until
left
surpassesright
. Notice this happens whenleft
is at the element that is greater than the pivot, andright
should stop at the element that is smaller than the pivot. In the following example,left
stops at6
andright
stops at5
.When we get
left > right
, we swapA[right]
withpivot
. This places the pivot in its correct position.We then recursively call quicksort, where we continue partitioning, on the left and right sub-arrays.
For example, if we do the partitioning on the right sub-array,
we start with
pivot
as element at index6
,left = 7
andright = 8
.we increment
left
till eitherA[left] > pivot
orleft > right
. Ifleft > right
, we shouldn’t decrementright
tillA[right] < pivot
. In the following example,left
stops at9
andright
remains at8
.we then have to swap
A[right]
andpivot
. This places the pivot in its correct position.we then recursively call quicksort on the left and right sub-arrays, but there is no right sub-array, so we only call quicksort on the left sub-array.
14.4.2. Pseudocode#
We write divide the pseudocode for quicksort into two function. The first function is the partitioning function, which takes in the array, the left
index, and the right
index.
Set
pivotInd
toleft
holding the index of the pivot element.Set
left
toleft + 1
to start from the next element.Increment
left
tillA[left] > pivot
orleft > right
.Decrement
right
tillA[right] < pivot
orleft > right
.If
left < right
, swapA[left]
andA[right]
.Otherwise, swap
A[right]
andA[pivotInd]
.Repeat steps 3-6 until
left > right
.
The second function is the quicksort function, which takes in the sub-array, with the low and high index, holding the left most index of the sub-array and the rightmost index of the sub-array, respectively.
If
low < high
, call the partitioning function on the sub-array from indexlow
tohigh
, and thereleft
will be set tolow
andright
will be set tohigh
.Partitioning function returns the index of the pivot element, which we will call
pivotInd
.Call quicksort on the left sub-array from
low
topivotInd - 1
.Call quicksort on the right sub-array from
pivotInd + 1
tohigh
.
14.4.3. Implementation#
The following code snippet shows the implementation of partition and quicksort sort functions. Download quicksort.c
if you want to play with the code.
Code
1#include <stdbool.h>
2#include <stdio.h>
3
4void swap(int list[], int left, int right) {
5 int t = list[right];
6 list[right] = list[left];
7 list[left] = t;
8}
9
10void printArray(int list[], int listLength) {
11 for (int i = 0; i < listLength; i++) {
12 printf("%d ", list[i]);
13 }
14 printf("\n");
15}
16
17int partition(int list[], int low, int high) {
18 int pivot = low, left = low + 1, right = high;
19 printf("left = %d, right = %d\n", left, right);
20 while (true) {
21 while (left <= right && list[left] <= list[pivot]) {
22 left++;
23 }
24
25 while (left <= right && list[right] > list[pivot]) {
26 right--;
27 }
28
29 if (left < right) {
30 swap(list, left, right);
31 } else {
32 swap(list, pivot, right);
33 return right;
34 }
35 }
36}
37
38void quicksortHelper(int list[], int low, int high) {
39 if (low < high) {
40 int pivot = partition(list, low, high);
41
42 printArray(list, 9);
43
44 quicksortHelper(list, low, pivot - 1);
45 quicksortHelper(list, pivot + 1, high);
46 }
47}
48
49void quicksort(int list[], int length) {
50 quicksortHelper(list, 0, length - 1);
51}
52
53int main(void) {
54 int list[9] = {10, 14, 8, 13, 20, 3, 6, 9, 4};
55
56 quicksort(list, 9);
57 printArray(list, 9);
58 return 0;
59}
Output
left = 1, right = 8 3 4 8 9 6 10 20 13 14 left = 1, right = 4 3 4 8 9 6 10 20 13 14 left = 2, right = 4 3 4 8 9 6 10 20 13 14 left = 3, right = 4 3 4 6 8 9 10 20 13 14 left = 7, right = 8 3 4 6 8 9 10 14 13 20 left = 7, right = 7 3 4 6 8 9 10 13 14 20 3 4 6 8 9 10 13 14 20
In-progress!