You are on page 1of 65

1

Intentional ambiguity

2
3
13 45 14 56
34
32 31
21 78

Select Pivot

13 45 14 56
34
32 31
21 78

4
13 45 14 56
34
32 31
21 78

Partition around Pivot

13 31 21 56
34 45
14 32
78

5
13 31 21 56
34 45
14 32
78

Quicksort recursively

13 14 21 31 32 34 45 56 78

13 14 21 31 32 34 45 56 78

6
7
8
9
10
11
12
13
Select Pivot 13, 32, 45, 34, 21,31, 56, 78

14
Select Pivot 13, 32, 45, 34, 21,31, 56, 78

Swap Pivot 13, 32, 45, 78, 21,31, 56, 34


and last element

15
Select Pivot 13, 32, 45, 34, 21,31, 56, 78

Swap Pivot 13, 32, 45, 78, 21,31, 56, 34


and last element

i j

16
Move i right until
an element larger
than the pivot is 13, 32, 45, 78, 21,31, 56, 34
found
i j

17
Move i right until
an element larger
than the pivot is 13, 32, 45, 78, 21,31, 56, 34
found
i
Move j left until an
element smaller
than the pivot is
13, 32, 45, 78, 21,31, 56, 34
found

i j

18
Move i right until
an element larger
than the pivot is 13, 32, 45, 78, 21, 31, 56, 34
found

Move j left until an


element smaller
than the pivot is
13, 32, 45, 78, 21, 31, 56, 34
found

i is smaller than j,
so swap the
elements
13, 32, 31, 78, 21, 45, 56, 34
i j
19
Move i right until
an element larger
than the pivot is 13, 32, 31, 78, 21, 45, 56, 34
found
i j

20
Move i right until
an element larger
than the pivot is 13, 32, 31, 78, 21,45, 56, 34
found
i j
Move j left until an
element smaller
than the pivot is
13, 32, 31, 78, 21,45, 56, 34
found
i j

21
Move i right until
an element larger
than the pivot is 13, 32, 31, 78, 21, 45, 56, 34
found

Move j left until an


element smaller
than the pivot is
13, 32, 31, 78, 21, 45, 56, 34
found

i is smaller than j,
so swap the
elements
13, 32, 31, 21, 78, 45, 56, 34
i j
22
Move i right until
an element larger 13, 32, 31, 21, 78,45, 56, 34
than the pivot is
found
i,j

23
Move i right until
an element larger 13, 32, 31, 21, 78, 45, 56, 34
than the pivot is
found
i,j
Move j left until an
element smaller
than the pivot is
13, 32, 31, 21, 78, 45, 56, 34
found
j i

24
Move i right until
an element larger 13, 32, 31, 21, 78, 45, 56, 34
than the pivot is
found

Move j left until an


element smaller
than the pivot is
13, 32, 31, 21, 78, 45, 56, 34
found

i and j have
crossed, swap
pivot with element
13, 32, 31, 21, 34, 45, 56, 78
at i
25
13, 32, 31, 21, 34, 45, 56, 78

At this stage we know


Every element at position p < i is less than the pivot
Every element at position p > i is greater than the pivot

26
27
28
29
30
31
/**
* Quicksort algorithm (driver).
*/
template <class Comparable>
void quicksort( vector<Comparable> & a )
{
quicksort( a, 0, a.size( ) - 1 );
}

32
/**
* Standard swap
*/
template <class Comparable>
inline void swap( Comparable & obj1,
Comparable & obj2 )
{
Comparable tmp = obj1;
obj1 = obj2;
obj2 = tmp;
}
33
/** Return median of left, center, and right.
* Order these and hide the pivot.
*/
template <class Comparable>
const Comparable & median3( vector<Comparable> & a,
int left, int right )
{
int center = ( left + right ) / 2;
if ( a[ center ] < a[ left ] )
swap( a[ left ], a[ center ] );
if ( a[ right ] < a[ left ] )
swap( a[ left ], a[ right ] );
if ( a[ right ] < a[ center ] )
swap( a[ center ], a[ right ] );

// Place pivot at position right - 1


swap( a[ center ], a[ right - 1 ] );
return a[ right - 1 ];
} 34
/**
* Return median of left, center, and right.
* Order these and hide the pivot.
*/
template <class Comparable>
const Comparable & median3( vector<Comparable> & a,
int left, int right )
{
int center = ( left + right ) / 2;
if ( a[ center ] < a[ left ] ) Sort the numbers at left,
swap( a[ left ], a[ center ] ); Right and center
if ( a[ right ] < a[ left ] )
swap( a[ left ], a[ right ] ); Smallest ends up at left,
if ( a[ right ] < a[ center ] )
swap( a[ center ], a[ right ] ); largest ends up at right

// Place pivot at position right - 1


swap( a[ center ], a[ right - 1 ] );
return a[ right - 1 ];
}
35
36
s ......... C ......... L After sort

Left Center Right

37
s ......... C ......... L After sort

Left Center Right

s ......... L ......... C After swap

Left Center Right

38
s ......... C ......... L After sort

Left Center Right

s ......... L ......... C After swap

Left Center Right


s ......... L ......... C After initialization
of i and j
Left Center Right

i j

39
What is the problem here?

s ......... C ......... L After sort

Left Center Right

s ......... L ......... C After swap

Left Center Right


s ......... L ......... C After initialization
of i and j
Left Center Right

i j

40
s ......... C ......... X L After sort
Left Center Right

41
s ......... C ......... X L After sort
Left Center Right

After the partitioning, we know that L will be to the right


of C, so why put it to the left first and then fix?

s ......... X ......... C L After swap


Left Center Right
Right-1

42
s ......... C ......... X L After sort
Left Center Right

After the partitioning, we know that L will be to the right


of C, so why put it to the left first and then fix?

s ......... X ......... C L After swap


Left Center Right
Right-1

We can initalize j to Right – 2, and i to Left+1

s ......... X ......... C L After swap


Left Center Right

i j 43
/**
* Return median of left, center, and right.
* Order these and hide the pivot.
*/
template <class Comparable>
const Comparable & median3( vector<Comparable> & a,
int left, int right )
{
int center = ( left + right ) / 2;
if ( a[ center ] < a[ left ] )
swap( a[ left ], a[ center ] );
if ( a[ right ] < a[ left ] )
swap( a[ left ], a[ right ] );
if ( a[ right ] < a[ center ] )
swap( a[ center ], a[ right ] );
Place median at
right - 1
// Place pivot at position right - 1
swap( a[ center ], a[ right - 1 ] );
return a[ right - 1 ];
} 44
/**
* Internal quicksort method that makes recursive calls.
* Uses median-of-three partitioning and a cutoff of 10.
* a is an array of Comparable items.
* left is the left-most index of the subarray.
* right is the right-most index of the subarray.
*/
template <class Comparable>
void quicksort( vector<Comparable> & a,
int left, int right )
{
if ( left + 10 <= right )
{
Comparable pivot = median3( a, left, right );
45
// Begin partitioning
int i = left, j = right - 1;
for ( ; ; )
{
while ( a[ ++i ] < pivot ) { }

while ( pivot < a[ --j ] ) { }

if ( i < j )
swap( a[ i ], a[ j ] );
else
break;
}
46
swap( a[ i ], a[ right - 1 ] ); // Restore pivot

quicksort( a, left, i - 1 ); // Sort small elements


quicksort( a, i + 1, right ); // Sort large elements
}
else // Do an insertion sort on the subarray
insertionSort( a, left, right );
}

47
/**
* Internal insertion sort routine for subarrays
* that is used by quicksort.
* a is an array of Comparable items.
* left is the left-most index of the subarray.
* right is the right-most index of the subarray.
*/
template <class Comparable>
void insertionSort( vector<Comparable> & a, int left, int right )
{
for ( int p = left + 1; p <= right; p++ )
{
Comparable tmp = a[ p ];
int j;

for ( j = p; j > left && tmp < a[ j - 1 ]; j-- )


a[ j ] = a[ j - 1 ];
a[ j ] = tmp;
}
} 48
49
T ( N )  T ( i )  T ( N  i  1 )  cN

50
T ( N )  T ( i )  T ( N  i  1 )  cN

Time to solve the subproblems

Time to partition

51
T ( N )  T ( i )  T ( N  i  1 )  cN
Worst Case
• The pivot is the smallest element always
• i = 0 (assuming T(0) =T(1) = 0)

T ( N )  T ( N  1 )  cN

52
T ( N )  T ( i )  T ( N  i  1 )  cN
Worst Case
• The pivot is the smallest element always
• i = 0 (assuming T(0) =T(1) = 0)

T ( N )  T ( N  1 )  cN


N

T ( N )  T ( 1)  c i
2
O( N )
i 2

53
T ( N )  T ( i )  T ( N  i  1 )  cN
Best Case
• The pivot is always at the middle
• We assume T(0) =T(1) = 0
• We assume two subparts are equal!

54
T ( N )  T ( i )  T ( N  i  1 )  cN
Best Case
• The pivot is always at the middle
• We assume T(0) =T(1) = 0
• We assume two subparts are equal!

N
T ( N )  2T ( )  cN
2

55
T ( N )  T ( i )  T ( N  i  1 )  cN
Best Case
• The pivot is always at the middle
• We assume T(0) =T(1) = 0
• We assume two subparts are equal!

N
T ( N )  2T ( )  cN  O ( N log N )
2

56
T ( N )  T ( i )  T ( N  i  1 )  cN
Average Case:
We assume each of the sizes of S1 is
equally likely (with probability 1/N)

Average value of T(i) (and also T(N-i-1)) is

1 N 1

N 
j
T(
0
j)

57
Thus the equation becomes
2 N  1 
T(N )    T ( j )   cN
N  j  0 

which when multiplied by N becomes

N  1 
NT ( N )  2  T ( j )   c N 2
 j  0 

which we can telescope with one more equation


N  2 
( N  1)T ( N  1)  2  T ( j )   c ( N  1) 2

 j  0 
58
Subtracting
N  1 
NT ( N )  2  T ( j )   c N 2
 j  0 

N  2 
( N  1)T ( N  1)  2  T ( j )   c ( N  1) 2
 j  0 
gives
NT ( N )  ( N  1)T ( N  1)  2T ( N  1)  2cN  c

59
Rearranging and dropping c gives
NT ( N )  ( N  1)T ( N  1)  2cN

Dividing by N(N+1)
T ( N ) T ( N  1) 2c
 
N 1 N N 1

Now telescoping all the way down to T(2) we get


T(N ) T ( 1) N 1
1
  2c 
N 1 2 i 3 i

60
T(N ) T ( 1) N 1
1
  2c 
N 1 2 i 3 i

Now T(1) is 0 and the sum is

3
ln( N  1)  0.577   O (log N )
2
Thus

T ( N )  O ( N log N )
61
62
63
64
65

You might also like