Quick Sort
Quick Sort
Quicksort
●
The basic quicksort algorithm is recursive (Follows Divide and
Conquer strategy)
» Chosing the pivot
» Deciding how to partition
» Dealing with duplicates
●
Wrong decisions give quadratic (n2) run times
●
Good decisions give n log n run time
The Quicksort Algorithm
●
The basic algorithm Quicksort(S) has 4 steps
✔ If the number of elements in S is 0 or 1, return
✔ Pick any element P in S. It is called the pivot.
✔Partition S – {P} (the remaining elements in S) into two disjoint groups: Split the
array into two parts – one with elements larger than the
pivot and the other with elements smaller than the pivot.
✔ L = {x Î S – {P}|x < P}
✔ R = {x Î S – {P}|x >= P}
✔Recursively repeat the algorithm for both halves of the original
array: Return the results of Quicksort(L) followed by P followed by Quicksort(R)
Quicksort
● Divide step:
–Pick any element (pivot) P in S P
–Partition S – {P} into two disjoint groups
S1 = {x Î S – {P} | x < P}
S
S2 = {x Î S – {P} | x ³ P}
● Combine step: the sorted S1 (by the time returned from recursion),
followed by P, followed by the sorted S2 (i.e., nothing extra needs to P
be done) S2
S1
24 45 17 31 50 85 63 96
Example
85 24 63 45 17 31 96 50
24 45 17 31 50 85 63 96
24 45 17 31 85 63 96
Example
85 24 63 45 17 31 96 50
24 45 17 31 50 85 63 96
24 45 17 31 85 63 96
Example
85 24 63 45 17 31 96 50
24 45 17 31 50 85 63 96
24 45 17 31 85 63 96
24 17 31 45
Example
85 24 63 45 17 31 96 50
24 45 17 31 50 85 63 96
24 45 17 31 85 63 96
24 17 31 45
24 17 45
Example
85 24 63 45 17 31 96 50
24 45 17 31 50 85 63 96
24 45 17 31 85 63 96
24 17 31 45
24 17 45
Example
85 24 63 45 17 31 96 50
24 45 17 31 50 85 63 96
24 45 17 31 85 63 96
24 17 31 45
17 24 45
Example
85 24 63 45 17 31 96 50
24 45 17 31 50 85 63 96
24 45 17 31 85 63 96
24 17 31 45
17 24 45
24
Example
85 24 63 45 17 31 96 50
24 45 17 31 50 85 63 96
24 45 17 31 85 63 96
24 17 31 45
17 24 45
Example
85 24 63 45 17 31 96 50
24 45 17 31 50 85 63 96
24 45 17 31 85 63 96
17 24 31 45
45
Example
85 24 63 45 17 31 96 50
24 45 17 31 50 85 63 96
24 45 17 31 85 63 96
17 24 31 45
Example
85 24 63 45 17 31 96 50
24 45 17 31 50 85 63 96
17 24 31 45 85 63 96
Example
85 24 63 45 17 31 96 50
17 24 31 45 50 85 63 96
85 63 96
Example
85 24 63 45 17 31 96 50
17 24 31 45 50 85 63 96
85 63 96
Example
85 24 63 45 17 31 96 50
17 24 31 45 50 85 63 96
85 63 96
Example
85 24 63 45 17 31 96 50
17 24 31 45 50 85 63 96
85 63 96
85 63
Example
85 24 63 45 17 31 96 50
17 24 31 45 50 85 63 96
85 63 96
85 63
Example
85 24 63 45 17 31 96 50
17 24 31 45 50 85 63 96
85 63 96
63 85
Example
85 24 63 45 17 31 96 50
17 24 31 45 50 85 63 96
85 63 96
63 85
Example
85 24 63 45 17 31 96 50
17 24 31 45 50 85 63 96
63 85 96
Example
85 24 63 45 17 31 96 50
17 24 31 45 50 63 85 96
Example
17 24 31 45 50 63 85 96
Algorithm
●
Now let us look the following:
–Algorithm
–Analysis
–Impact of choosing the pivot on runtime of the algorithm
Quicksort - Pseudocode
quickSort(int array[], int low, int high)
{
if (low >= high)
{
return //Base Case, we’re done
}
else
{
//partition array around pivot value array[low]
//partition_Index contains the new location of pivot value
if(LEFT<RIGHT)
swap(array[LEFT],array[RIGHT])
}
// swap pivot and the element at the array location where LEFT/RIGHT cross
array[low]=array[RIGHT];
array[RIGHT]=pivot;
//return the location where LEFT/RIGHT cross
return RIGHT;
}
Trace of the Quicksort
Algorithm
0 1 2 3 4 5
quickSort(arr,0,5) 6 5 9 12 3 4
quickSort(arr,0,5)
0 1 2 3 4 5
partition(arr,0,5) 6 5 9 12 3 4
quickSort(arr,0,5)
0 1 2 3 4 5
partition(arr,0,5) 6 5 9 12 3 4
pivot= ?
Partition Initialization...
quickSort(arr,0,5)
0 1 2 3 4 5
partition(arr,0,5) 6 5 9 12 3 4
pivot=6
Partition Initialization...
quickSort(arr,0,5)
0 1 2 3 4 5
partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left
Partition Initialization...
quickSort(arr,0,5)
0 1 2 3 4 5
partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right
Partition Initialization...
quickSort(arr,0,5)
0 1 2 3 4 5
partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right
0 1 2 3 4 5
partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right
quickSort(arr,0,5)
0 1 2 3 4 5
partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right
0 1 2 3 4 5
partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right
quickSort(arr,0,5)
0 1 2 3 4 5
partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right
quickSort(arr,0,5)
0 1 2 3 4 5
partition(arr,0,5) 6 5 9 12 3 4
pivot=6
left right
0 1 2 3 4 5
partition(arr,0,5) 6 5 4 12 3 9
pivot=6
left right
0 1 2 3 4 5
partition(arr,0,5) 6 5 4 12 3 9
pivot=6
left right
0 1 2 3 4 5
partition(arr,0,5) 6 5 4 12 3 9
pivot=6
left right
quickSort(arr,0,5)
0 1 2 3 4 5
partition(arr,0,5) 6 5 4 12 3 9
pivot=6
left right
0 1 2 3 4 5
partition(arr,0,5) 6 5 4 12 3 9
pivot=6
left right
quickSort(arr,0,5)
0 1 2 3 4 5
partition(arr,0,5) 6 5 4 12 3 9
pivot=6
left right
0 1 2 3 4 5
partition(arr,0,5) 6 5 4 3 12 9
pivot=6
left right
0 1 2 3 4 5
partition(arr,0,5) 6 5 4 3 12 9
pivot=6
left right
0 1 2 3 4 5
partition(arr,0,5) 6 5 4 3 12 9
pivot=6
left right
0 1 2 3 4 5
partition(arr,0,5) 6 5 4 3 12 9
pivot=6
left
right
quickSort(arr,0,5)
0 1 2 3 4 5
partition(arr,0,5) 6 5 4 3 12 9
pivot=6
left
right
0 1 2 3 4 5
partition(arr,0,5) 6 5 4 3 12 9
pivot=6
left
right
0 1 2 3 4 5
partition(arr,0,5) 3 5 4 6 12 9
pivot=6
left
right
0 1 2 3 4 5
partition(arr,0,5) 3 5 4 6 12 9
pivot=6
left
right
return 3
0 1 2 3 4 5
quickSort(arr,0,5) 3 5 4 6 12 9
pivot
position
3 5 4 6 12 9
quickSort(arr,0,2) quickSort(arr,4,5)
0 1 2 4 5
3 5 4 12 9
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)
0 1 2 4 5
3 5 4 12 9
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)
0 1 2 4 5
3 5 4 12 9
Partition Initialization...
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)
0 1 2 4 5
3 5 4 12 9
Partition Initialization...
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)
0 1 2 4 5
3 5 4 12 9
left
Partition Initialization...
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)
0 1 2 4 5
3 5 4 12 9
left right
Partition Initialization...
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)
0 1 2 4 5
3 5 4 12 9
left right
quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)
0 1 2 4 5
3 5 4 12 9
left right
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)
0 1 2 4 5
3 5 4 12 9
left
right
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)
0 1 2 4 5
3 5 4 12 9
left
right
quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)
0 1 2 4 5
3 5 4 12 9
left
right
quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,0,2)
0 1 2 4 5
3 5 4 12 9
left
right
return 0
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
0 1 2 4 5
3 5 4 12 9
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
0 1 2 12 9
3 5 4
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
0 1 2 12 9
3 5 4
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
0 1 2 12 9
3 5 4
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4
Partition Initialization...
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4
Partition Initialization...
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4
left
Partition Initialization...
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4
left right
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4
left right
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4
left right
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4
right
left
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4
right
left
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 5 4
right
left
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 4 5
right
left
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
partition(arr,1,2)
0 1 2 12 9
3 4 5
right
left
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
0 12 9
3
quickSort(arr,1,1)
4
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
0 12 9
3
quickSort(arr,1,1)
4
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
0 12 9
3
quickSort(arr,1,1)
4
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
partition(arr,4,5)
quickSort(arr,0,0) 4 5
quickSort(arr,1,2)
0 9 12
3
quickSort(arr,1,1)
4
quickSort(arr,0,5)
quickSort(arr,0,2) quickSort(arr,4,5)
3
quickSort(arr,1,1)
1 quickSort(arr,4,4)
4
4
9
Analysis
●
Running time
–pivot selection: constant time, i.e. O(1)
–partitioning: linear time, i.e. O(N)
–running time of the two recursive calls
–
●
T(N)=T(i)+T(N-i-1)+cN where c is a constant
–i: number of elements in partition S1 and N-i-1 is the remaining
elements in partition S2
–cN is the time required for partitioning at each level of the recursive
call.
●
BASE CASE: T(n)=c, for n=1
Analysis – Worst case
●
When will the worst case happen?
–The pivot is the smallest element every time
–The Partition is always unbalanced
Example – Worst case
Example – Worst case
17 24 31 45 50 63 85 96
Example – Worst case
17 24 31 45 50 63 85 96
Example – Worst case
17 24 31 45 50 63 85 96
17 24 31 45 50 63 85 96
Example – Worst case
17 24 31 45 50 63 85 96
17 24 31 45 50 63 85 96
17 24 31 45 50 63 85
Example – Worst case
17 24 31 45 50 63 85 96
17 24 31 45 50 63 85 96
17 24 31 45 50 63 85
Example – Worst case
17 24 31 45 50 63 85 96
17 24 31 45 50 63 85 96
17 24 31 45 50 63 85
Example – Worst case
17 24 31 45 50 63 85 96
17 24 31 45 50 63 85 96
17 24 31 45 50 63 85
17 24 31 45 50 63
15 7 9 3 13 5 11 2 14 6 10 1 12 4 8
Example – Best case
7 3 6 2 5 1 4 8 15 9 13 11 14 10 12
Example – Best case
7 3 6 1 5 2 4 8 15 9 13 11 14 10 12
7 3 6 1 5 2 4 15 9 13 11 14 10 12
Example – Best case
7 3 6 1 5 2 4 8 15 9 13 11 14 10 12
7 3 6 1 5 2 4 15 9 13 11 14 10 12
Example – Best case
7 3 5 1 6 2 4 8 15 9 13 11 14 10 12
3 1 2 4 7 5 6 9 11 10 12 15 13 14
Example – Best case
7 3 5 1 6 2 4 8 15 9 13 11 14 10 12
3 1 2 4 7 5 6 9 11 10 12 15 13 14
3 1 2 7 5 6 9 11 10 15 13 14
Example – Best case
7 3 5 1 6 2 4 8 15 9 13 11 14 10 12
3 1 2 4 7 5 6 99 11
11 10
10 12
12 15
15 13
13 14
14
3 1 2 7 5 6 9 11 10 15 13 14
Example – Best case
7 3 5 1 6 2 4 8 15 9 13 11 14 10 12
3 1 2 4 7 5 6 9 11 10 12 15 13 14
1 2 3 5 6 7 9 10 11 13 14 15
What is size at each level?
n 7 3 5 1 6 2 4 8 15 9 13 11 14 10 12
n-1 3 1 2 4 7 5 6 9 11 10 12 15 13 14
n-3 1 2 3 5 6 7 9 10 11 13 14 15
n-7 1 3 5 7 9 11 13 15
Best Case, more precisely
• S0(n) = n
• S1(n) = n - 1
• S2(n) = (n – 1) – 2 = n – (1 + 2) = n-3
• S3(n) = ((n – 1) – 2) - 4 = n – (1 + 2 + 4) = n-7
• …
• Si(n) = n – ( 1 + 2 + 22+ … + 2i-1) = n - 2i + 1
• Height is O(log n)
• No more than n work is done at any one level
• Best case time complexity is O(n log n)
Analysis – Best case
●
When will the Best case happen?
–Pivot is the middle element every time and splits the
array in halves
–The Partition is always balanced
–Considering the recurrence relation:
T(N)=T(i)+T(N-i-1)+cN
●
Substitute i=N/2 for the best case, because one of the
partitions always contains almost halve of the elements.
●
T(N)=T(N/2)+T(N/2-1)+cN
●
T(N)≈2T(N/2)+cN
●
We have already seen this recurrence for the Merge
Sort which has O(Nlog2N) running time.
Analysis – Average case
●
In the average, we do not know where the split
happens.
–We take all possible values of split locations, add
all their complexities and divide with N to get the
average case complexity.
●
The cost to quicksort N items equals N units for the
partitioning plus the cost of the two recursive calls
●
The average cost of each recursive call equals the
average over all possible sub-problem sizes
Average cost of the recursive calls
Recurrence Relation
……
Nth Harmonic no is O(log N)
Thank you