Quicksort

Quicksort is an in-place $$O(n \log n)$$ sort that uses $$O(\log n)$$ stack memory. Its worst case is $$O(n^2)$$. It is not stable, and not adaptive.

The partition
A partition is a function that takes an array, chooses an element called the "pivot", and arranges the array in such a way that every element smaller than the pivot is to the front of it and every element larger than the pivot is to the back of it.

The sort
To Quicksort an array, first partition it, then Quicksort left and right of the pivot recursively.

Example
Take the array {7 12 6 11 3 15 1 14 2 16 8 10 9 13 5 4}.

first, partition it (arbitrarily choosing the lowest element as the pivot):

[6 3 1 2 5 4] [7] [12 11 15 14 16 8 10 9 13]

Recursively sort the left half:

[3 1 2 5 4] [6] [7] [12 11 15 14 16 8 10 9 13]

[1 2] [3] [5 4] [6] [7] [12 11 15 14 16 8 10 9 13]

[1] [2] [3] [4] [5] [6] [7] [12 11 15 14 16 8 10 9 13]

Append:

[1 2 3 4 5 6] [7] [12 11 15 14 16 8 10 9 13]

Recursively sort the right half:

[1 2 3 4 5 6] [7] [11 8 10 9] [12] [16 14 15 13]

[1 2 3 4 5 6] [7] [8 10 9] [11] [12] [16 14 15 13]

[1 2 3 4 5 6] [7] [8] [10] [9] [11] [12] [16 14 15 13]

[1 2 3 4 5 6] [7] [8] [10] [9] [11] [12] [13] [14] [15] [16]

Append: [1 2 3 4 5 6 7 8 10 9 11 12 13 14 15 16]

Sorted!

Pseudocode
There are two main partition functions, Lomuto and Hoare. Lomuto's partition (also known as LL pointers) is easier to understand but slower. Hoare's partition (also known as LR pointers) is slightly more difficult to understand, but it is more efficient because it makes fewer swaps on average than Lomuto's partition. The code for both is displayed below.

Lomuto
procedure partition(array arr,int lo,int hi) do elem pivot = arr[lo] int i = lo - 1; for j = lo to hi - 1 do if arr[j] <= pivot do i ++ swap arr[i] and arr[j] end if end for return i + 1 end procedure quicksort(array arr,int lo,int hi) do if hi <= lo do return end if int j = partition(arr,lo,hi) quicksort(arr,lo,j - 1); quicksort(arr,j + 1,hi); end

Hoare
procedure partition(array arr,int lo,int hi) do elem pivot = arr[floor((lo + hi) / 2)] int i = lo; int j = hi; while true do while arr[i] < pivot i ++ end while while arr[j] > pivot j -- end while if i < j do swap arr[i] and arr[j] i ++; j --; end if else return j      end else end while end procedure quicksort(array arr,int lo,int hi) do if hi <= lo do return end if int j = partition(arr,lo,hi) quicksort(arr,lo,j); quicksort(arr,j,hi); end