You are on page 1of 15

Quick Sort

AKRAM_LOQMAN_

Quick Sort

AKRAM_LOQMAN_
Like in MERGESORT, we use Divide-and-Conquer:
1. Divide: partition A[p..r] into two subarrays A[p..q-1] and
A[q+1..r] such that each element of A[p..q-1] is A[q],
and each element of A[q+1..r] is A[q]. Compute q as
part of this partitioning.

2. Conquer: sort the subarrays A[p..q-1] and A[q+1..r] by


recursive calls to QUICKSORT.

3. Combine: the partitioning and recursive sorting leave us


with a sorted A[p..r] no work needed here.
An obvious difference is that we do most of the work in the
divide stage, with no work at the combine one.
AKRAM_LOQMAN_

MERGESORT
A[q+1..r] A[p..q-1] A[p..r] .1
A[q] A[p..q-1]
q A[q] A[q+1..r]

A[q+1..r] A[p..q-1] .2

QUICKSORT

.3
-- A[p..r]

AKRAM_LOQMAN_
First, we have to select a pivot element among the
elements of the given array.

Which array item should be selected as pivot?


Somehow we have to select a pivot, and we hope
that we will get a good partitioning.
If the items in the array arranged randomly, we
choose a pivot randomly.
We can choose the first or last element as a pivot
(it may not give a good partitioning).
We can use different techniques to select the
pivot. AKRAM_LOQMAN_

Pivot

Pivot
Pivot

Pivot
Pivot

Pivot
AKRAM_LOQMAN_
Strategy 1: Pick the first element in S
Works only if input is random
What if input S is sorted, or even mostly
sorted?
All the remaining elements would go into either
S1 or S2!
Terrible performance!

Why worry about sorted input?


Remember Quick Sort is recursive, so sub-
problems could be sorted
Plus mostly sorted input is quite frequent
AKRAM_LOQMAN_

S2 S1

AKRAM_LOQMAN_
Strategy 2: Pick the pivot randomly

Would usually work well, even for


mostly sorted input

Unless the random number generator


is not quite random!

Plus random number generation is an


expensive operation
AKRAM_LOQMAN_

Pivot

AKRAM_LOQMAN_
Strategy 3: Median-of-three Partitioning

Ideally, the pivot should be the median of input


array S
Median = element in the middle of the sorted sequence

Would divide the input into two almost equal


partitions
Unfortunately, its hard to calculate median quickly,
without sorting first!
So find the approximate median
Pivot = median of the left-most, right-most and center
element of the array S
Solves the problem of sorted input AKRAM_LOQMAN_

Pivot
S

= Pivot
S
AKRAM_LOQMAN_
Example: Median-of-three Partitioning
Let input S = {6, 1, 4, 9, 0, 3, 5, 2, 7, 8}

S[left] = 6

S[right] = 8

S[center] = 0
Pivot
= Median of S[left], S[right], and S[center]
= median of 6, 8, and 0 = 6
= S[left] = 6 AKRAM_LOQMAN_

S = {6, 1, 4, 9, 0, 3, 5, 2, 7, 8}

S[left] = 6

S[right] = 8

S[center] = 0
Pivot
S[left], S[right], and S[center] =
6, 8, and 0 = 6 =
AKRAM_LOQMAN_
S[left] =
QUICKSORT (A, p,r)
1 If p<r
2 then q PARTITION (A,p,r)
3 QUICKSORT(A,p,q-1)
4 QUICKSORT(A,q+1,r)
PARTITION(A, p,r)
1 x A[r]
2 i p-1
3 for j p to r-1
4 do if A[j] < x
5 then i i+1
6 exchange A[i] A[j]
7 exchange A[i+1] A[r]
8 return i+1 AKRAM_LOQMAN_

AKRAM_LOQMAN_
1 2 3 4 5 6 7 8
(a) 2 8 7 1 3 5 6 4
i p,j r
i=0
p=j=1
r=8 PARTITION(A, p,r)
1 x A[r] x=4
2 i p-1 i=0
3 for j p to r-1 j=1
4 do if A[j] < x 2 < 4 ? YES
5 then i i+1 i=1
i=1 6 exchange A[i] A[j] exchange 2 & 2
j=1 7 exchange A[i+1] A[r]
p=1 8 return i+1
r=8
AKRAM_LOQMAN_

1 2 3 4 5 6 7 8
(b) 2 8 7 1 3 5 6 4
i=1 p,i j r
j=1
p=1
r=8 PARTITION(A, p,r)
1 x A[r]
2 i p-1
3 for j p to r-1 j=2
4 do if A[j] < x 8 < 4 ? NO
5 then i i+1
i=1 6 exchange A[i] A[j]
j=2 7 exchange A[i+1] A[r]
p=1 8 return i+1
r=8
AKRAM_LOQMAN_
1 2 3 4 5 6 7 8
(c) 2 8 7 1 3 5 6 4
i=1 p,i j r
j=2
p=1
r=8 PARTITION(A, p,r)
1 x A[r]
2 i p-1
3 for j p to r-1 j=3
4 do if A[j] < x 7 < 4 ? NO
5 then i i+1
i=1 6 exchange A[i] A[j]
j=3 7 exchange A[i+1] A[r]
p=1 8 return i+1
r=8
AKRAM_LOQMAN_

1 2 3 4 5 6 7 8
(d) 2 8 7 1 3 5 6 4
i=1 p,i j r
j=3
p=1 2 1 7 8 3 5 6 4
r=8 p i j r

PARTITION(A, p,r)
1 x A[r]
2 i p-1
3 for j p to r-1 j=4
i=2 4 do if A[j] < x 1 < 4 ? YES
j=4 5 then i i+1 i=2
p=1 6 exchange A[i] A[j] exchange 8 & 1
7 exchange A[i+1] A[r]
r=8 8 return i+1
AKRAM_LOQMAN_
1 2 3 4 5 6 7 8
(e) 2 1 7 8 3 5 6 4
i=2
j=4
p=1 2 1 3 8 7 5 6 4
r=8 p i j r
PARTITION(A, p,r)
1 x A[r]
2 i p-1
3 for j p to r-1 j=5
i=3 4 do if A[j] < x 3 < 4 ? YES
j=5 5 then i i+1 i=3
6 exchange A[i] A[j] exchange 7 & 3
p=1 7 exchange A[i+1] A[r]
r=8 8 return i+1
AKRAM_LOQMAN_

1 2 3 4 5 6 7 8
(f) 2 1 3 8 7 5 6 4
i=3 p i j r
j=5 PARTITION(A, p,r)
p=1 1 x A[r]
r=8 2 i p-1
3 for j p to r-1 j=6
4 do if A[j] < x 5 < 4 ? NO
5 then i i+1
6 exchange A[i] A[j]
7 exchange A[i+1] A[r]
i=3 8 return i+1
j=6
p=1
r=8
AKRAM_LOQMAN_
1 2 3 4 5 6 7 8
(g) 2 1 3 8 7 5 6 4
i=3 p i j r
j=6 PARTITION(A, p,r)
p=1 1 x A[r]
r=8 2 i p-1
3 for j p to r-1 j=7
4 do if A[j] < x 6 < 4 ? NO
5 then i i+1
6 exchange A[i] A[j]
7 exchange A[i+1] A[r]
i=3 8 return i+1
j=7
p=1
r=8
AKRAM_LOQMAN_

1 2 3 4 5 6 7 8
(h) 2 1 3 8 7 5 6 4
i=3
j=7
p=1 2 1 3 4 7 5 6 8
r=8 p i j r
PARTITION(A, p,r)
1 x A[r]
2 i p-1
3 for j p to r-1
4 do if A[j] < x
5 then i i+1
6 exchange A[i] A[j]
7 exchange A[i+1] A[r] exchange 4 & 8
8 return i+1
AKRAM_LOQMAN_
return 4 (q=4) q
We cut the array size in half each time

So the depth of the recursion in log n

At each level of the recursion, all the


partitions at that level do work that is
linear in n

(log n) * (n) = (n log n)


AKRAM_LOQMAN_

log n

(log n) * (n) = (n log n)

AKRAM_LOQMAN_
Worst-case partitioning
One region has one element and the other has n 1
elements

Maximally unbalanced
In the worst case, recursion may be n levels deep (for
an array of size n)

But the partitioning work done at each level is still n


(n) * (n) = (n2)

So worst case for Quick Sort is (n2)


AKRAM_LOQMAN_

n-1

n
(n
n
(n) * (n) = (n2)
(n2)
AKRAM_LOQMAN_
Quick Sort is the fastest known sorting
algorithm

For optimum efficiency, the pivot must be


chosen carefully

Median of three is a good technique for


choosing the pivot

However, no matter what you do, there will be


some cases where Quick Sort runs in O(n2)
time AKRAM_LOQMAN_

Pivot

Pivot

AKRAM_LOQMAN_ O(n2)

You might also like