Data Structures and Algorithms (H) Lecture 5 Notes
QuickSort
Introduction
The quick sort is also a divide-and-conquer algorithm just like the merge sort:
- Divide:
- Pick some element called pivot.
- Move it to its final location in the sorted sequence s.t. all smaller elements are to its left, larger ones are to its right.
- Conquer:
- Recursively sort subarrays for smaller and larger elements.
- Combine:
- No work needed here since after the recursion the array is sorted.
QuickSort: The Algorithm

Initially we will cal QuickSort(A,1,A.length).
The differences to merge sort are:
- We split the array at
, the position of the pivot in sorted array, and we don’t know in advance, instead it is revealed by Partition. - There is no combine step at the end.
Partitionplays a similar role toMerge.
Partition(A,p,r)
The Partition function rearranges the subarray
The main ideas are:
- Scan the subarray from left to right.
- Build up a subarray
of elements smaller or equal to the pivot. - Build up a subarray
of elements larger than the pivot. - When reaching the end of the array, put the pivot in the right place.
The pseudocode for Partition goes as follows: 
An example run of the Partition algorithm:

Correctness
We prove the correctness of Partition by using the loop
invariant:
- Loop invariant: At the beginning of the
-th iteration, we have (let denotes the pivot) and . - Initialization: Since at the initialization
and , the invariant trivially holds. - Maintanence:
- If the
ifon line 4 is false, thenis greater than , and the algorithm will increate the to so that subarry grows one element to contain . - If the
ifon line 4 is true, then we swapwith and then increase both and by 1. - This maintains the invariant.
- If the
- Termination: After the last swap in line 7,
and Partitionreturns the position of.
Runtime
The runtime is straightforward to find:
Worst-case and Best-case Partitionings
The overall runtime depends on how the array is partitioned
as that determines the sizes
Worst-case Partitioning
The worst case is attained when Partition always produces one
subproblem with
Best-case Partitioning
The best case is where we split the problem into two subproblems of
sizes
Towards an Average Case
To reach the average case, we assume that all elements of the array
are distinct, and each split
Proof. We use induction on
Base case:
. And we need to prove that : This trivially holds. (e.g., for
) Inductive case: Assume fo every
we have and prove for that The highlighted part is based on fact that when a summation has the form , where is a monotonically increasing function, then we can approximate it by integrals: So we have Q.E.D.
Improvements to QuickSort
Quick sort is often fast in practice because of the small constants in the asymptotic runtime. There are some improvements (not comprehensive) we can apply on the quick sort:
- Improvements for handling equal values:
- Partition into smaller, equal, and larger elements.
- So we only need to sort smaller and larger subarrays.
- Choose the pivot as median of 3 elements.
- Slightly faster in practice, but still has a quadratic worst-case runtime.
- Dual-Pivot Quick Sort by Vladimir Yaroslavskiy.
- Use two pivots instead of one and partition array into 3 areas.
A Randomized Version of QuickSort
Choosing the right pivot element can be tricky since we have no idea a priori which element can be a good pivot. A (surprisingly good) solution is to leave it to chance:

- Title: Data Structures and Algorithms (H) Lecture 5 Notes
- Author: Zhige Chen
- Created at : 2025-10-12 19:16:26
- Updated at : 2025-10-12 19:26:00
- Link: https://nofe1248.github.io/2025/10/12/dsaa-lec-5/
- License: This work is licensed under CC BY-NC-SA 4.0.