QuickSort - a recursive search algorithm

Objective

  • Take a list of elements and put them in order, i.e. sort them.

Suppose we have the following array and we wish to sort them using quicksort algorithm

Idea:

1) we can select the first item in the list and use it as a "Split Value" to split the list in 2...where by everything on the left of the list is < this Split Value and everything on the right is >= this SplitValue.

2)then we recursively call split on the two lists, on the left and right of the split value.

 

Recurisive Algorithm


// Recursive quick sort algorithm
//PSUEDO CODE!!!!!!!!!!!!!!!
 
template <class  ItemType >
void  QuickSort ( ItemType A[ ] ,  int first, int  last )	
	
//  Pre:   first <= last
//  Post: Sorts array A[ first. .last ] into 
//  ascending order
{
	if ( first < last )                    //  general case

	{ int splitPoint;

     splitPoint = Split ( A, first, last) ;		

	  // A[ first ] . . A[splitPoint - 1 ] <= splitVal
	  // A[ splitPoint ] = splitVal
	  // A[ splitPoint + 1 ] . . A[ last ] > splitVal

	  QuickSort( A,  first,  splitPoint - 1 ) ;
	  QuickSort( A,  splitPoint + 1,  last );
	}
           
} 



//PSUEDO CODE !!!!
Split(A, first, last)
{	
     splitVal =  A[first];   //use first element as splitVal
     i = first;  //counter starting at first
 

     for(j=first+1 thru last)
       {    if(A[j] <= splitval)
             {  i= i +1; 
                //swap new A[i] with A[j]
                temp = A[j];
                A[j] = A[i];
                A[i] = temp;
              }
       }

     //now swap A[first](contains splitVal) with A[i]
     temp = A[i];
     A[i] = A[first];
     A[first] = A[i];
      
     //return new splitPoint location, the location of splitVal
     return i;
}
            



//RESULTS During First call to SPlit
Split(A, 0, 7)

1) A = [9 20 6 10 14 3 60 11 ],
   splitVal = 9, splitPoint = 0 (first position)

2) After first for loop  i = 0, j=2
   A = [9 20 6 10 14 3 60 11]

3) After second for loop  i=1   , j=3
   A = [9 6 20 10 14 3 60 11]

4) After 3rd for loop i=1  , j=4
   A = [9 6 20 10 14 3 60 11]

5) After 4th for loop i=1,j=5
   A = [9 6 20 10 14 3 60 11]

6) After 5th for loop i=2 , j=6
   A = [9 6 3 10 14 20 60 11]

7) After 6th for loop i=2, j=7
   A = [9 6 3 10 14 20 60 11]

8) After 7th for loop i=2, j=8
   A = [9 6 3 10 14 20 60 11]

9) DONE - as j is past last
   //now swap A[first] and A[i]
   A = [3 6 9 10 14 20 60 11]
   splitPoint = i = 2

NOW WE MUST Call QuickSort Recursively
On the 2 sub arrays to left and right of SplitPoint that
Need sorting
QuickSort(A, 0, 1)
QuickSort(A, 3, 7)
            


CONCEPT OF SPLIT

....at any one time in the the For loop of Split have

Any A[x]  where x <=i MEANS A[x] <=splitVal
Any A[x]  where x > i AND x < j  MEANS A[x] > splitVal
Any A[x]  where x >= j MEANS A[x] = yet unknown (not looked at)

[ splitVal  LLLLLL   GGGGGG   UUUUU]


VERY EFFICIENT WITH SPACE!!!!
AN "IN PLACE ALGORITHM"

Running Time

It depends on the order of the original array elements!

If each split divides the subarray approximately in half,

BEST CASE

    • there will be only logN splits
    • QuickSort is O(N*logN).

 

But, if the original array was sorted to begin with, the recursive calls will split up the array into parts of unequal length, with one part empty, and the other part containing all the rest of the array except for split value itself.

WORST CASE

    • In this case, there can be as many as N-1 splits
    • QuickSort is O(N^2).

HOW CAN WE MAKE AVERAGE CASE = BEST CASE?

answer 1: radomize / scatter input in array to make "sure" not an ordered array

answer 2: change code and randomize the splitPoint you start with --- swap it initally with first some RADOMLY selected value between first and last before for loop of split.

SOLUTION: RANDOMIZED Quicksort Algorithm

 

THIS is a technique used in computer science to try to avoid sorted input data.

 

© Lynne Grewe