3 Divide and Conquer 5 Quicksort
3 Divide and Conquer 5 Quicksort
Quick Sort
Alexander S. Kulikov
Steklov Institute of Mathematics at St. Petersburg
Russian Academy of Sciences
Algorithmic Toolbox
Data Structures and Algorithms
Outline
1 Overview
2 Algorithm
3 Random Pivot
5 Equal Elements
6 Final Remarks
Quick Sort
6 4 8 2 9 3 9 4 7 6 1
Example: quick sort
6 4 8 2 9 3 9 4 7 6 1
partition with respect to x = A[1]
in particular, x is in its final position
1 4 2 3 4 6 6 9 7 8 9
≤6 >6
Example: quick sort
6 4 8 2 9 3 9 4 7 6 1
partition with respect to x = A[1]
in particular, x is in its final position
1 4 2 3 4 6 6 9 7 8 9
sort the two parts recursively
1 2 3 4 4 6 6 7 8 9 9
Outline
1 Overview
2 Algorithm
3 Random Pivot
5 Equal Elements
6 Final Remarks
QuickSort(A, ℓ, r )
if ℓ ≥ r :
return
m ← Partition(A, ℓ, r )
{A[m] is in the final position}
QuickSort(A, ℓ, m − 1)
QuickSort(A, m + 1, r )
ℓ r
A
ℓ r
A
m ← Partition(A, ℓ, r )
A ≤x x >x
m
ℓ r
A
m ← Partition(A, ℓ, r )
A ≤x x >x
m
QuickSort(A, ℓ, m − 1) QuickSort(A, m + 1, r )
A x
sorted
Partitioning: example
the pivot is x = A[ℓ]
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 9 8 9 4 7 6 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 9 8 9 4 7 6 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 9 8 9 4 7 6 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 9 8 9 4 7 6 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 9 8 9 4 7 6 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 4 8 9 9 7 6 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 4 8 9 9 7 6 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 4 8 9 9 7 6 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 4 8 9 9 7 6 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 4 8 9 9 7 6 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 4 8 9 9 7 6 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 4 6 9 9 7 8 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 4 6 9 9 7 8 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 4 6 9 9 7 8 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 4 6 9 9 7 8 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
ℓ r
6 4 2 3 4 6 9 9 7 8 1
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
in the end, move A[ℓ] to its final place
ℓ r
6 4 2 3 4 6 1 9 7 8 9
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
in the end, move A[ℓ] to its final place
ℓ r
6 4 2 3 4 6 1 9 7 8 9
j i
Partitioning: example
the pivot is x = A[ℓ]
move i from ℓ + 1 to r maintaining the
following invariant:
A[k] ≤ x for all ℓ + 1 ≤ k ≤ j
A[k] > x for all j + 1 ≤ k ≤ i
in the end, move A[ℓ] to its final place
ℓ r
1 4 2 3 4 6 6 9 7 8 9
j i
Partition(A, ℓ, r )
x ← A[ℓ] {pivot}
j ←ℓ
for i from ℓ + 1 to r :
if A[i] ≤ x:
j ←j +1
swap A[j] and A[i]
{A[ℓ + 1 . . . j] ≤ x, A[j + 1 . . . i] > x}
swap A[ℓ] and A[j]
return j
Outline
1 Overview
2 Algorithm
3 Random Pivot
5 Equal Elements
6 Final Remarks
Unbalanced Partitions
T (n) = n + T (n − 1):
T (n) = n + T (n − 1):
T (n) = n + T (n − 5) + T (4):
T (n) = 2T (n/2) + n:
T (n) = 2T (n/2) + n:
log10 n
log10/9 n
Balanced Partitions
T (n) = T (n/10) + T (9n/10) + O(n)
log10 n
log10/9 n
sorted A
n/4 n/2 n/4
Theorem
Assume that all the elements of A[1 . . . n] are
pairwise different. Then the average running
time of RandomizedQuickSort(A) is
O(n log n) while the worst case running time
is O(n2).
Theorem
Assume that all the elements of A[1 . . . n] are
pairwise different. Then the average running
time of RandomizedQuickSort(A) is
O(n log n) while the worst case running time
is O(n2).
Remark
Averaging is over random numbers used by
the algorithm, but not over the inputs.
Outline
1 Overview
2 Algorithm
3 Random Pivot
5 Equal Elements
6 Final Remarks
Proof Ideas: Comparisons
the running time is proportional to the
number of comparisons made
Proof Ideas: Comparisons
the running time is proportional to the
number of comparisons made
balanced partition are better since they
reduce the number of comparisons
needed:
5 1 2 4 7 3 6
1 5 4 3 6 7 2 3 1 2 4 6 5 7
1 is min 3, 1, 2 < 6, 5, 7
Proof Ideas: Probability
A 5 1 8 9 2 4 7 3 6
A′ 1 2 3 4 5 6 7 8 9
Proof Ideas: Probability
A 5 1 8 9 2 4 7 3 6
A′ 1 2 3 4 5 6 7 8 9
2
Prob (1 and 9 are compared) =
9
Proof Ideas: Probability
A 5 1 8 9 2 4 7 3 6
A′ 1 2 3 4 5 6 7 8 9
2
Prob (1 and 9 are compared) =
9
2
Prob (1 and 9 are compared) =
9
2 Algorithm
3 Random Pivot
5 Equal Elements
6 Final Remarks
Equal Elements
m ← Partition(A, ℓ, r )
such that
for all ℓ ≤ k ≤ m1 − 1, A[k] < x
for all m1 ≤ k ≤ m2, A[k] = x
for all m2 + 1 ≤ k ≤ r , A[k] > x
ℓ r
A
ℓ r
A <x =x >x
m1 m2
RandomizedQuickSort(A, ℓ, r )
if ℓ ≥ r :
return
k ← random number between ℓ and r
swap A[ℓ] and A[k]
(m1, m2) ← Partition3(A, ℓ, r )
{A[m1 . . . m2] is in final position}
RandomizedQuickSort(A, ℓ, m1 − 1)
RandomizedQuickSort(A, m2 + 1, r )
Outline
1 Overview
2 Algorithm
3 Random Pivot
5 Equal Elements
6 Final Remarks
Tail Recursion Elimination
QuickSort(A, ℓ, r )
while ℓ < r :
m ← Partition(A, ℓ, r )
QuickSort(A, ℓ, m − 1)
ℓ←m+1
QuickSort(A, ℓ, r )
while ℓ < r :
m ← Partition(A, ℓ, r )
if (m − ℓ) < (r − m):
QuickSort(A, ℓ, m − 1)
ℓ←m+1
else:
QuickSort(A, m + 1, r )
r ←m−1
QuickSort(A, ℓ, r )
while ℓ < r :
m ← Partition(A, ℓ, r )
if (m − ℓ) < (r − m):
QuickSort(A, ℓ, m − 1)
ℓ←m+1
else:
QuickSort(A, m + 1, r )
r ←m−1
Worst-case space requirement: O(log n)
Intro Sort
runs quick sort with a simple
deterministic pivot selection heuristic
(say, median of the first, middle, and
last element)
Intro Sort
runs quick sort with a simple
deterministic pivot selection heuristic
(say, median of the first, middle, and
last element)
if the recursion depth exceeds a certain
threshold c log n the algorithm switches
to heap sort
Intro Sort
runs quick sort with a simple
deterministic pivot selection heuristic
(say, median of the first, middle, and
last element)
if the recursion depth exceeds a certain
threshold c log n the algorithm switches
to heap sort
the running time is O(n log n) in the
worst case
Conclusion