Runtime anaylsis of the
Quick Sort algorithm
Running time of
the Quick Sort algorithm:
The running time of
Quick Sort depends
on
how
partition( )
splits up the
input array
Recall the
partition(A, s, e) algorithm :
Input: [ 5 1 7 2 8 9 3 6 ]
Result: [ 1 2 3 5 7 8 9 6 ]
<-------> <------------>
< 5 >= 5
Important fact:
The running time
of Quick Sort depends
on how large
the 2 array halves are !
Recurrence relation for the
running time of the
Quick Sort algorithm
Suppose the
partition(A, s, e) algorithm
partitions the
input as
follows :
<------------------- n ------------------->
Input: [ P .. .. .. .. .. .. .. .. .. .. .. ]
Result: [ .. .. .. .. .. .. P .. .. .... .. .. .. .. ]
<----- k -----> <----- n-k-1 ------>
Recall the
Quick Sort
algorithm:
public static > void sort(T[] A, int s, int e) // n = e-s
{
if ( e - s <= 1 ) // Base case
return;
int pivotLoc = partition(A, s, e) ; // Running time = n
sort(A, s, pivotLoc); // Input size = k
sort(A, pivotLoc+1, e); // Input size = n-k-1
}
Running time T(n) for
input size n :
T(n) = T(k) + T(n-k-1) + n
The best case running time
of Quick Sort
The worst case running time
of Quick Sort
The
worst case
running time of the
Quick Sort algorithm happens
when:
The partition( ) algorithm
always divides the
input array into
(1) array containing the pivot and
(2) an array with n-1 elements
In this case , we have:
T(n) = T(0 ) + T(n-1 ) + n
= 0 + T(n-1) + n = T(n-1) + n
Solve the
recurrence relation with
telescoping :
T(n) = T(n-1) + n T(n-1) = T(n-2) + (n-1)
= T(n-2) + (n-1) + n T(n-2) = T(n-3) + (n-2)
= T(n-3) + (n-2) + (n-1) + n
= ...
= T(1) + 2 + 3 + 4 + ... + (n-1) + n T(1) = 0
= 0 + 2 + 3 + 4 + ... + (n-1) + n (Triangular sum)
= n(n+1)/2 - 1
= O(n2 ) <--- Worst case running time
Example that makes
Quick Sort achieve the
worst case running time
When
Quick Sort is
used to
sort a
sorted array ,
it will result in the
worst case
running time of
O(n2 )
Example:
A[] = [ 1 2 3 4 5 6 7 8 ... ]
^
|
pivot
After partition(A, 0, n) :
A[] = [ 1 2 3 4 5 6 7 8 ... ]
^
|
pivot
And so on...
Because the
pivot is
always the
smallest value ,
partition( ) will
always produce:
An array containing the
pivot
An array containing the
other
n-1 elements
Commonly used practice with
Quick Sort
Commonly used
practice when using
Quick Sort :
Note:
Quick Sort will
achieve the
average
running time
performance with
a randomized
input array
We will study the
average
running time of
Quick Sort
next
The average case running time
of Quick Sort
Recall the
recurrence relation
for the running time of
Quick Sort is:
T(n) = T(k ) + T(n-k -1) + n where k = final pos of the pivot
Depending on
the value of
k , the
recurrence relation for
T(n) are:
T(n) = T(0 ) + T(n-1 ) + n if k = 0
T(n) = T(1 ) + T(n-2 ) + n if k = 1
...
T(n) = T(n-1 ) + T(0 ) + n if k = n-1
Each
value of
k is
equally likely to
occur , so we can
take the average by:
T(n) = T(0 ) + T(n-1 ) + n if k = 0
T(n) = T(1 ) + T(n-2 ) + n if k = 1
...
T(n) = T(n-1 ) + T(0 ) + n if k = n-1 (average = sum/n)
----------------------------------------------------------------
nT(n) = (T(0) + ... + T(n-1)) + (T(n-1) + ... + T(0)) + n*n
nT(n) = 2T(0) + 2T(1) + ... + 2T(n-1) + n*n
T(n) = 2/n*T(0) + 2/n*T(1) + ... + 2/n*T(n-1) + n
Solution:
T(n) = 2(n+1) Hn
~= 2(n+1)lg(n+1)
=
O(nlog(n))
Solving the
recurrence relation for the
average case
The recurrence relation for the
average case
running time of
Quick Sort is:
T(n) = 2/n*T(0) + 2/n*T(1) + ... + 2/n*T(n-1) + n
I will show you the solution procedure
if time permits ....
We need a
base case
(termination condition ) for the
recurrence relation ....
Solving the
recurrence relation for the
average case
Quick Sort on an
array of
size = 1 will
return
immediately :
T(n) = 2/n*T(0) + 2/n*T(1) + ... + 2/n*T(n-1) + n
T(1) = 1
We assign the cost = 1
for running time of
the test e - s <= 1
Solving the
recurrence relation for the
average case
We first
multiply the
general equation by
n :
T(n) = 2/n*T(0) + 2/n*T(1) + ... + 2/n*T(n-1) + n
T(1) = 1
nT(n) = 2*T(0) + 2*T(1) + ... + 2*T(n-2) + 2*T(n-1) + n2
Now substitute :
n = n-1 in the
equation ...
Solving the
recurrence relation for the
average case
If we substitute
n = n-1
, we will
get a similar equation :
T(n) = 2/n*T(0) + 2/n*T(1) + ... + 2/n*T(n-1) + n
T(1) = 1
nT(n) = 2*T(0) + 2*T(1) + ... + 2*T(n-2) + 2*T(n-1) + n2
(n-1)T(n-1) = 2*T(0) + 2*T(1) + ... + 2*T(n-2) + (n-1)2
Subtract the
2 equations are
simplify :
Solving the
recurrence relation for the
average case
If we substitute
n = n-1
, we will
get a similar equation :
T(n) = 2/n*T(0) + 2/n*T(1) + ... + 2/n*T(n-1) + n
T(1) = 1
nT(n) = 2*T(0) + 2*T(1) + ... + 2*T(n-2) + 2*T(n-1) + n2
(n-1)T(n-1) = 2*T(0) + 2*T(1) + ... + 2*T(n-2) + (n-1)2
nT(n) - (n-1)T(n-1) = 2*T(n-1) + n2 - (n-1)2
= 2*T(n-1) + n2 - (n2 - 2n + 1)
= 2*T(n-1) + n2 - n2 + 2n - 1
= 2*T(n-1) + 2n - 1
Solving the
recurrence relation for the
average case
Consolidate the
term
T(n-1)
that appears on
both side of the
equation :
T(n) = 2/n*T(0) + 2/n*T(1) + ... + 2/n*T(n-1) + n
T(1) = 1
nT(n) = 2*T(0) + 2*T(1) + ... + 2*T(n-2) + 2*T(n-1) + n2
(n-1)T(n-1) = 2*T(0) + 2*T(1) + ... + 2*T(n-2) + (n-1)2
nT(n) - (n-1)T(n-1) = 2*T(n-1) + n2 - (n-1)2
= 2*T(n-1) + n2 - (n2 - 2n + 1)
= 2*T(n-1) + n2 - n2 + 2n - 1
= 2*T(n-1) + 2n - 1
nT(n) = (n-1+2)T(n-1) + 2n - 1
Solving the
recurrence relation for the
average case
Simplify :
T(n) = 2/n*T(0) + 2/n*T(1) + ... + 2/n*T(n-1) + n
T(1) = 1
nT(n) = 2*T(0) + 2*T(1) + ... + 2*T(n-2) + 2*T(n-1) + n2
(n-1)T(n-1) = 2*T(0) + 2*T(1) + ... + 2*T(n-2) + (n-1)2
nT(n) - (n-1)T(n-1) = 2*T(n-1) + n2 - (n-1)2
= 2*T(n-1) + n2 - (n2 - 2n + 1)
= 2*T(n-1) + n2 - n2 + 2n - 1
= 2*T(n-1) + 2n - 1
nT(n) = (n+1)T(n-1) + 2n - 1
Solving the
recurrence relation for the
average case
We obtain a
simpler
recurrence relation
for T(n) :
T(n) = 2/n*T(0) + 2/n*T(1) + ... + 2/n*T(n-1) + n
T(1) = 1
nT(n) = 2*T(0) + 2*T(1) + ... + 2*T(n-2) + 2*T(n-1) + n2
(n-1)T(n-1) = 2*T(0) + 2*T(1) + ... + 2*T(n-2) + (n-1)2
nT(n) - (n-1)T(n-1) = 2*T(n-1) + n2 - (n-1)2
= 2*T(n-1) + n2 - (n2 - 2n + 1)
= 2*T(n-1) + n2 - n2 + 2n - 1
= 2*T(n-1) + 2n - 1
nT(n) = (n+1)T(n-1) + 2n - 1
T(n) = (n+1)/n * T(n-1) + 2 - 1/n
Solving the
recurrence relation for the
average case
In order to solve this
recurrence relation , we
apply a different
telescoping
technique :
T(n) = 2/n*T(0) + 2/n*T(1) + ... + 2/n*T(n-1) + n
T(1) = 1
nT(n) = 2*T(0) + 2*T(1) + ... + 2*T(n-2) + 2*T(n-1) + n2
(n-1)T(n-1) = 2*T(0) + 2*T(1) + ... + 2*T(n-2) + (n-1)2
nT(n) - (n-1)T(n-1) = 2*T(n-1) + n2 - (n-1)2
= 2*T(n-1) + n2 - (n2 - 2n + 1)
= 2*T(n-1) + n2 - n2 + 2n - 1
= 2*T(n-1) + 2n - 1
nT(n) = (n+1)T(n-1) + 2n - 1
T(n) = (n+1)/n * T(n-1) + 2 - 1/n with T(1) = 1
Trick: divide both side by n+1
T(n)/(n+1) = 1/n * T(n-1) + 2/(n+1) - 1/(n+1)n
= T(n-1)/n + 2/(n+1) - 1/(n+1)n
Solving the
recurrence relation for the
average case
We can (finally )
solve the
simplified
recurrence relation with
telescoping :
T(n)/(n+1) = T(n-1)/n + 2/(n+1) - 1/(n+1)n with T(1) = 1
Solving the
recurrence relation for the
average case
Substitue
n = n - 1
the expression for
T(n)/(n+1) and
obtain the
following
equation :
T(n)/(n+1) = T(n-1)/n + 2/(n+1) - 1/(n+1)n with T(1) = 1
T(n-1)/n = T(n-2)/(n-1) + 2/n - 1/n(n-1)
Solving the
recurrence relation for the
average case
Substitue
n = n - 2
the expression for
T(n)/(n+1) and
obtain the
following
equation :
T(n)/(n+1) = T(n-1)/n + 2/(n+1) - 1/(n+1)n with T(1) = 1
T(n-1)/n = T(n-2)/(n-1) + 2/n - 1/n(n-1)
T(n-2)/(n-1) = T(n-3)/(n-2) + 2/(n-1) - 1/(n-1)(n-2)
Solving the
recurrence relation for the
average case
Substitue
n = n - 3
the expression for
T(n)/(n+1) and
obtain the
following
equation :
T(n)/(n+1) = T(n-1)/n + 2/(n+1) - 1/(n+1)n with T(1) = 1
T(n-1)/n = T(n-2)/(n-1) + 2/n - 1/n(n-1)
T(n-2)/(n-1) = T(n-3)/(n-2) + 2/(n-1) - 1/(n-1)(n-2)
T(n-3)/(n-2) = T(n-4)/(n-3) + 2/(n-2) - 1/(n-2)(n-3)
Solving the
recurrence relation for the
average case
And so on ...
telescope until we reach
the base case
T(1) :
T(n)/(n+1) = T(n-1)/n + 2/(n+1) - 1/(n+1)n with T(1) = 1
T(n-1)/n = T(n-2)/(n-1) + 2/n - 1/n(n-1)
T(n-2)/(n-1) = T(n-3)/(n-2) + 2/(n-1) - 1/(n-1)(n-2)
T(n-3)/(n-2) = T(n-4)/(n-3) + 2/(n-2) - 1/(n-2)(n-3)
....
T(2)/3 = T(1) /2 + 2/3 - 1/(3*2)
Solving the
recurrence relation for the
average case
Add all the
equations and
obtain a new
equation :
T(n)/(n+1) = T(n-1)/n + 2/(n+1) - 1/(n+1)n with T(1) = 1
T(n-1)/n = T(n-2)/(n-1) + 2/n - 1/n(n-1)
T(n-2)/(n-1) = T(n-3)/(n-2) + 2/(n-1) - 1/(n-1)(n-2)
T(n-3)/(n-2) = T(n-4)/(n-3) + 2/(n-2) - 1/(n-2)(n-3)
....
T(2)/3 = T(1) /2 + 2/3 - 1/(3*2)
Add all the equations :
T(n)/(n+1) + T(n-1)/n + T(n-2)/(n-1) + ... + T(2)/3
= T(n-1)/n + T(n-2)/(n-1) + ... + T(2)/3 + T(1)/2
+ 2/(n+1) + 2/n + 2/(n-1) + ... + 2/3
- 1/(n+1)n - 1/n(n-1) - 1/(n-1)(n-2) - ... 1/(3*2)
Solving the
recurrence relation for the
average case
❮
❯