The quicksort algorithm sorts an array by first selecting a pivot entry
and partitioning the array about that element.
The partition operation rearranges the entries, placing the pivot entry
in its proper sort position.
After the partition, entries before (in index order) the pivot entry are
less than the pivot entry.
Entries after the pivot entry are greater than or equal to the pivot
entry.
This is illustrated in the following diagram, where the index
`geq`

points to the pivot entry.

lo | geq | hi | |

< | = | >= |

Then the quicksort algorithm recursively sorts the entries before the pivot entry and the entries after the pivot entry.

After checking if there is more than one element (if not then just return), a pivot element is selected and swapped with the end entry. This is done to keep the pivot entry in a known place. It will later be swapped into its proper place.

Two variables `geq`

and `unk`

are set equal to
`lo`

, the lowest index in the array segment.
This indicates that the "<" and ">=" segments of the array are
currently empty.

A variable `end`

is set equal to `hi - 1`

, where
`hi`

is the index just beyond the end of the segment.
This results in the following picture.
The partition loop only works with the portion outlined in blue.

unk | ||

geq | ||

lo | end | hi |

? | = |

Here `?`

indicates unknown entries - entries that have not yet
been examined.

The two preceding pictures can be generalized into a single picture that covers both.

lo | geq | unk | end | hi |

< | >= | ? | = |

Here, `<`

indicates entries that are less than the pivot
and `>=`

indicates entries that are greater than or equal
to the pivot.

Since this picture covers both the starting picture, the end result, and intermediate steps, it can be used as a loop invariant.

Each iteration of the loop checks the entry at index `unk`

.
If it is less than `piv`

then the entry is swapped with the
entry at `geq`

and both `geq`

and `unk`

are advanced.
Otherwise `unk`

is advanced.
In either case, the loop invariant is preserved.

When finally `unk == end`

we have the following picture.

unk | |||

lo | geq | end | hi |

< | >= | = |

Now the entry at index `geq`

is swapped with the pivot at
index `end`

.
This results in the following picture.

lo | geq | hi | |

< | = | >= |

After achieving this picture, the array can be completely sorted by
recursively sorting the `<`

and `>=`

regions.