Quick Sort

Pseudocode


Analysis
• Performance of quick sort is highly dependent on how the even the partitioning is
• Partitioning depends on pivot choice
Best Case
• Ideal pivot choice: always choose the median element
• Evenly divides the list into two equal parts
• Two calls to quick sort on lists roughly half the size
• A linear number of comparisons to partition
• Recurrence: $$C(n)=2C(\frac{n}{2})+n$$
• By the Master Theorem, $O(n log n)$
Worst Case
• Worst pivot choice: an extremal element
• Divides into an empty list and a list of size $(n − 1)$
• Only one recursive call is necessary, but on a list of size $(n − 1)$
• Recurrence: $$C(n) = C(n − 1) + n$$
• Back substitution yields $O(n^2)$
Average Case
• Even if the list is is split by a constant proportion, still $O(n log n)$
• A careful average case analysis also yields $$C(n) ≈ 1.38n log n$$
• Still O(n log n)
Pivot Choice: Pivot choice greatly affects performance; several strategies:
• Median-of-Three – Among three elements choose the median.
– Guarantees that the pivot choice will never be the worst case.
– Does not guarantee $Θ(n log n)$.
• Random Element – Randomly select an index for a pivot element.
– Guarantees average running time of $Θ(n log n)$.
– Extra work to randomly select a pivot.
• Linear Time Median Finding.
– An algorithm exists that runs in $Θ(n)$ time to find the median of $n$ objects.
– Guarantees $Θ(n log n)$ in all cases.
– Complicated; recursive; huge overhead.
Code Samples
1 | private static void quickSort (int a [] , int left , int right ) { |
1 | public static int partition (int a [] , int left , int right ) |
1 | void swap (int *a , int * b ) |
A good tutorial with a non-recursive C implementation: http://alienryderflex.com/quicksort/