Following is a typical recursive implementation of Quick Sort that uses last element as pivot.

C++

[pastacode lang=”cpp” manual=”%2F*%20A%20typical%20recursive%20C%2FC%2B%2B%20%20implementation%20of%20QuickSort%20*%2F%0A%20%0A%2F*%20This%20function%20takes%20last%20element%20as%20pivot%2C%20places%20%0A%20%20%20the%20pivot%20element%20at%20its%20correct%20position%20in%20sorted%20%0A%20%20%20array%2C%20and%20places%20all%20smaller%20(smaller%20than%20pivot)%0A%20%20%20to%20left%20of%20pivot%20and%20all%20greater%20elements%20to%20right%20%0A%20%20%20of%20pivot%20*%2F%0Aint%20partition%20(int%20arr%5B%5D%2C%20int%20l%2C%20int%20h)%0A%7B%0A%20%20%20%20int%20x%20%3D%20arr%5Bh%5D%3B%0A%20%20%20%20int%20i%20%3D%20(l%20-%201)%3B%0A%20%0A%20%20%20%20for%20(int%20j%20%3D%20l%3B%20j%20%3C%3D%20h-%201%3B%20j%2B%2B)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20if%20(arr%5Bj%5D%20%3C%3D%20x)%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20i%2B%2B%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20swap%20(%26arr%5Bi%5D%2C%20%26arr%5Bj%5D)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20swap%20(%26arr%5Bi%20%2B%201%5D%2C%20%26arr%5Bh%5D)%3B%0A%20%20%20%20return%20(i%20%2B%201)%3B%0A%7D%0A%20%0A%2F*%20A%5B%5D%20–%3E%20Array%20to%20be%20sorted%2C%20%0A%20%20l%20%20–%3E%20Starting%20index%2C%20%0A%20%20h%20%20–%3E%20Ending%20index%20*%2F%0Avoid%20quickSort(int%20A%5B%5D%2C%20int%20l%2C%20int%20h)%0A%7B%0A%20%20%20%20if%20(l%20%3C%20h)%0A%20%20%20%20%7B%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%2F*%20Partitioning%20index%20*%2F%0A%20%20%20%20%20%20%20%20int%20p%20%3D%20partition(A%2C%20l%2C%20h)%3B%20%0A%20%20%20%20%20%20%20%20quickSort(A%2C%20l%2C%20p%20-%201)%3B%20%20%0A%20%20%20%20%20%20%20%20quickSort(A%2C%20p%20%2B%201%2C%20h)%3B%0A%20%20%20%20%7D%0A%7D” message=”c++” highlight=”” provider=”manual”/]

JAVA

[pastacode lang=”java” manual=”%2F%20Java%20program%20for%20implementation%20of%20QuickSort%0Aclass%20QuickSort%0A%7B%0A%20%20%20%20%2F*%20This%20function%20takes%20last%20element%20as%20pivot%2C%0A%20%20%20%20%20%20%20places%20the%20pivot%20element%20at%20its%20correct%0A%20%20%20%20%20%20%20position%20in%20sorted%20array%2C%20and%20places%20all%0A%20%20%20%20%20%20%20smaller%20(smaller%20than%20pivot)%20to%20left%20of%0A%20%20%20%20%20%20%20pivot%20and%20all%20greater%20elements%20to%20right%0A%20%20%20%20%20%20%20of%20pivot%20*%2F%0A%20%20%20%20int%20partition(int%20arr%5B%5D%2C%20int%20low%2C%20int%20high)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20int%20pivot%20%3D%20arr%5Bhigh%5D%3B%0A%20%20%20%20%20%20%20%20int%20i%20%3D%20(low-1)%3B%20%2F%2F%20index%20of%20smaller%20element%0A%20%20%20%20%20%20%20%20for%20(int%20j%3Dlow%3B%20j%3C%3Dhigh-1%3B%20j%2B%2B)%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20If%20current%20element%20is%20smaller%20than%20or%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20equal%20to%20pivot%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(arr%5Bj%5D%20%3C%3D%20pivot)%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i%2B%2B%3B%0A%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20swap%20arr%5Bi%5D%20and%20arr%5Bj%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20int%20temp%20%3D%20arr%5Bi%5D%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20arr%5Bi%5D%20%3D%20arr%5Bj%5D%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20arr%5Bj%5D%20%3D%20temp%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%0A%20%20%20%20%20%20%20%20%2F%2F%20swap%20arr%5Bi%2B1%5D%20and%20arr%5Bhigh%5D%20(or%20pivot)%0A%20%20%20%20%20%20%20%20int%20temp%20%3D%20arr%5Bi%2B1%5D%3B%0A%20%20%20%20%20%20%20%20arr%5Bi%2B1%5D%20%3D%20arr%5Bhigh%5D%3B%0A%20%20%20%20%20%20%20%20arr%5Bhigh%5D%20%3D%20temp%3B%0A%20%0A%20%20%20%20%20%20%20%20return%20i%2B1%3B%0A%20%20%20%20%7D%0A%20%0A%20%20%20%20%2F*%20The%20main%20function%20that%20implements%20QuickSort()%0A%20%20%20%20%20%20arr%5B%5D%20–%3E%20Array%20to%20be%20sorted%2C%0A%20%20%20%20%20%20low%20%20–%3E%20Starting%20index%2C%0A%20%20%20%20%20%20high%20%20–%3E%20Ending%20index%20*%2F%0A%20%20%20%20void%20qSort(int%20arr%5B%5D%2C%20int%20low%2C%20int%20high)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20if%20(low%20%3C%20high)%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20pi%20is%20partitioning%20index%2C%20arr%5Bpi%5D%20is%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20now%20at%20right%20place%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20int%20pi%20%3D%20partition(arr%2C%20low%2C%20high)%3B%0A%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Recursively%20sort%20elements%20before%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20partition%20and%20after%20partition%0A%20%20%20%20%20%20%20%20%20%20%20%20qSort(arr%2C%20low%2C%20pi-1)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20qSort(arr%2C%20pi%2B1%2C%20high)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%7D” message=”java” highlight=”” provider=”manual”/] [ad type=”banner”]

PYTHON

[pastacode lang=”java” manual=”%23%20A%20typical%20recursive%20Python%20%20implementation%20of%20QuickSort%20*%2F%0A%20%20%0A%23%20This%20function%20takes%20last%20element%20as%20pivot%2C%20places%0A%23%20the%20pivot%20element%20at%20its%20correct%20position%20in%20sorted%0A%23%20array%2C%20and%20places%20all%20smaller%20(smaller%20than%20pivot)%0A%23%20to%20left%20of%20pivot%20and%20all%20greater%20elements%20to%20right%0A%23%20of%20pivot%0Adef%20partition(arr%2Clow%2Chigh)%3A%0A%20%20%20%20i%20%3D%20(%20low-1%20)%20%20%20%20%20%20%20%20%20%23%20index%20of%20smaller%20element%0A%20%20%20%20pivot%20%3D%20arr%5Bhigh%5D%20%20%20%20%20%23%20pivot%0A%20%20%0A%20%20%20%20for%20j%20in%20range(low%20%2C%20high)%3A%0A%20%20%0A%20%20%20%20%20%20%20%20%23%20If%20current%20element%20is%20smaller%20than%20or%0A%20%20%20%20%20%20%20%20%23%20equal%20to%20pivot%0A%20%20%20%20%20%20%20%20if%20%20%20arr%5Bj%5D%20%3C%3D%20pivot%3A%0A%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20increment%20index%20of%20smaller%20element%0A%20%20%20%20%20%20%20%20%20%20%20%20i%20%3D%20i%2B1%0A%20%20%20%20%20%20%20%20%20%20%20%20arr%5Bi%5D%2Carr%5Bj%5D%20%3D%20arr%5Bj%5D%2Carr%5Bi%5D%0A%20%20%0A%20%20%20%20arr%5Bi%2B1%5D%2Carr%5Bhigh%5D%20%3D%20arr%5Bhigh%5D%2Carr%5Bi%2B1%5D%0A%20%20%20%20return%20(%20i%2B1%20)%0A%20%20%0A%23%20The%20main%20function%20that%20implements%20QuickSort%0A%23%20arr%5B%5D%20–%3E%20Array%20to%20be%20sorted%2C%0A%23%20low%20%20–%3E%20Starting%20index%2C%0A%23%20high%20%20–%3E%20Ending%20index%0A%20%20%0A%23%20Function%20to%20do%20Quick%20sort%0Adef%20quickSort(arr%2Clow%2Chigh)%3A%0A%20%20%20%20if%20low%20%3C%20high%3A%0A%20%20%0A%20%20%20%20%20%20%20%20%23%20pi%20is%20partitioning%20index%2C%20arr%5Bp%5D%20is%20now%0A%20%20%20%20%20%20%20%20%23%20at%20right%20place%0A%20%20%20%20%20%20%20%20pi%20%3D%20partition(arr%2Clow%2Chigh)%0A%20%20%0A%20%20%20%20%20%20%20%20%23%20Separately%20sort%20elements%20before%0A%20%20%20%20%20%20%20%20%23%20partition%20and%20after%20partition%0A%20%20%20%20%20%20%20%20quickSort(arr%2C%20low%2C%20pi-1)%0A%20%20%20%20%20%20%20%20quickSort(arr%2C%20pi%2B1%2C%20high)%0A%20″ message=”java” highlight=”” provider=”manual”/]

The above implementation can be optimized in many ways

1) The above implementation uses last index as pivot. This causes worst-case behavior on already sorted arrays, which is a commonly occurring case. The problem can be solved by choosing either a random index for the pivot, or choosing the middle index of the partition or choosing the median of the first, middle and last element of the partition for the pivot. (See this for details)

2) To reduce the recursion depth, recur first for the smaller half of the array, and use a tail call to recurse into the other.

3) Insertion sort works better for small subarrays. Insertion sort can be used for invocations on such small arrays (i.e. where the length is less than a threshold t determined experimentally). For example, this library implementation of qsort uses insertion sort below size 7.

Despite above optimizations, the function remains recursive and uses function call stack to store intermediate values of l and h. The function call stack stores other bookkeeping information together with parameters. Also, function calls involve overheads like storing activation record of the caller function and then resuming execution.

The above function can be easily converted to iterative version with the help of an auxiliary stack. Following is an iterative implementation of the above recursive code.

[ad type=”banner”]

Output:

1 2 2 3 3 3 4 5

The above mentioned optimizations for recursive quick sort can also be applied to iterative version.

1) Partition process is same in both recursive and iterative. The same techniques to choose optimal pivot can also be applied to iterative version.

2) To reduce the stack size, first push the indexes of smaller half.

3) Use insertion sort when the size reduces below a experimentally calculated threshold.

[ad type=”banner”]