15 - Quicksort

Instead we can attempt to estimate the median element

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: using the median of the first, middle and last items in the array – a task that can be done in O(1) time. CPSC 260 Quicksort Page 12 Reducing the space requirements Definition: a recursive function is tail-recursive if in the general case the recursive call is the last operation to be executed in the function. Example: The following function is tail-recursive: v o i d m y F u n c( i n t N ) { if( N > 0 ) { c o u t < < N < < e n d l; m y F u n c( N – 1 ) ; } else cout << “base case” << endl; } CPSC 260 Quicksort Page 13 Example: The following function is not tail-recursive: v o i d m y O t h e r F u n c( i n t N ) { if( N > 0 ) { m y O t h e r F u n c( N – 1 ) ; c o u t < < N < < e n d l; } else cout << “base case” << endl; } CPSC 260 Quicksort Each of the functions myFunc and myOtherFunc has O(N) space requirements. Exercise: Write an iterative version of myFunc: In the case of the tail-recursive function, we can easily replace the recursive implementation with a functionally equivalent iterative version. Page 14 v o i d m y F u n c( i n t N ) { while( N > 0 ) { c o u t < < N < < e n d l; N = N – 1; } However, the iterative version will require only one activation record to be generated (as recursive calls are not being made) and hence the space requirements will be independent of N, in other words O(1). cout << “base case” << endl; } CPSC 260 Quicksort Page 15 Exercise: Determine the space complexity of the following tail-recursive function and re-write the function using iteration. What is the space complexity of the new function? void print( int N ) { if( n > 0 ) { cout << N % 10; print( N / 10 ); } } CPSC 260 Quicksort Page 17 CPSC 260 Quicksort Page 16 Quicksort is tail-recursive, so we can use an iteration… template< class i temType > v o i d Q u i c k s o r t( i t e m T y p e l i s t [ ] , i n t l e f t , i n t r i g h t ) / / P o s t c o n d i t i o n: l i s t e l e m e n t s b e t w e e n i n d e x l e f t a n d // index right have been sorted into increasing order { while( left < right ) { int pivotPosition = partition( list, left, right ); if( p ivotPosition - left < right - p ivotPosition ) { Q u i c k s o r t( l i s t , l e f t , p i v o t P o s i t i o n - 1 ) ; left = p ivotPosition + 1; } else { Q u i c k s o r t( l i s t , p i v o t P o s i t i o n + 1 , r i g h t ) ; right = p ivotPosition - 1; } } } CPSC 260 Quicksort Page 18 The solution is to sort the smaller partition recursively and the larger partition iteratively: In this case the number of recursive calls required to hit the base case is no more than !log 2 N " + 1 because we recursively sort partitions that are no bigger than N / 2. Hence, the space requirement in the worst case is O( log N ). Summary: by removing the tail-recursive call and recursively sorting the smaller partition, the time/space complexities for our improved Quicksort algorithm are as follows: Time complexity Best case: Average case: These are great exam questions! Worst case: Space complexity Best case: Average case: Worst case: CPSC 260 Quicksort Page 19 CPSC 260 Quicksort Page 20...
View Full Document

Ask a homework question - tutors are online