Intro to Quick Sort

  • Quick Sort is the most commonly used sorting algorithm today

  • Quick Sort was invented by Antony Hoare in 1959 and was honored as one of the top 10 algorithms in the 20th century...

  • Some facts on Quick Sort:

    • Is a divide and conquer recursive algorithm
      (just like Merge Sort)

    • Unlike Merge Sort, Quick Sort is an in-place algorithm
      (i.e.: do not use an extra array)

How does the Quick Sort algorithm work ?

  • Imagine you have N boxes and each box contains a number:

    
       |   |   |   |   |   |   |   |   |   |   |   |   |   |
       | 4 |   | 5 |   | 6 |   | 3 |   | 2 |   | 1 |   | 7 |
       +---+   +---+   +---+   +---+   +---+   +---+   +---+   
    

  • We select one of the number as pivot: (e.g.: the first value)

     pivot = 4
       |   |   |   |   |   |   |   |   |   |   |   |   |   |
       | 4 |   | 5 |   | 6 |   | 3 |   | 2 |   | 1 |   | 7 |
       +---+   +---+   +---+   +---+   +---+   +---+   +---+   
    

  • Then we partition the values into 2 subgroups: (1) values < pivot and (2) values ≥ pivot:

     
       |   |   |   |   |   |   |   |   |   |   |   |   |   |
       | 3 |   | 2 |   | 1 |   | 4 |   | 5 |   | 6 |   | 7 |
       +---+   +---+   +---+   +---+   +---+   +---+   +---+   
       <------ group 1 ---->   pivot   <------ group 2 ----->
    

  • We repeat (= recurse) the process for each subgroup !

Example of the Quick Sort algorithm

 partition(A,s,e) = partition array elements A[s] .. A[e-1]  using pivot = A[s]


 Steps (recursions) performed by the Quick Sort Algorithm:

        Index --> 0  1  2  3  4  5  6  7 

 Input A[]  =    [5, 4, 1, 7, 2, 9, 3, 6]          Pivot = 5




















Example of the Quick Sort algorithm

 partition(A,s,e) = partition array elements A[s] .. A[e-1]  using pivot = A[s]


 Steps (recursions) performed by the Quick Sort Algorithm:

        Index --> 0  1  2  3  4  5  6  7 

 Input A[]  =    [5, 4, 1, 7, 2, 9, 3, 6]          Pivot = 5
                  <-------------------->
 partition(A,0,8):          |
                            V

















Example of the Quick Sort algorithm

 partition(A,s,e) = partition array elements A[s] .. A[e-1]  using pivot = A[s]


 Steps (recursions) performed by the Quick Sort Algorithm:

        Index --> 0  1  2  3  4  5  6  7 

 Input A[]  =    [5, 4, 1, 7, 2, 9, 3, 6]          Pivot = 5
                  <-------------------->
 partition(A,0,8):          |
                            V
          A[]  = [2, 3, 4, 1, 5, 9, 7, 6]          Pivot = 2
                  <--------> 















Example of the Quick Sort algorithm

 partition(A,s,e) = partition array elements A[s] .. A[e-1]  using pivot = A[s]


 Steps (recursions) performed by the Quick Sort Algorithm:

        Index --> 0  1  2  3  4  5  6  7 

 Input A[]  =    [5, 4, 1, 7, 2, 9, 3, 6]          Pivot = 5
                  <-------------------->
 partition(A,0,8):          |
                            V
          A[]  = [2, 3, 4, 1, 5, 9, 7, 6]          Pivot = 2
                  <-------->     <----->
 partition(A,0,4):    |          (still need sorting)
                      V
          A[]  = [1, 2, 4, 3, 5, 9, 7, 6]          Pivot = 4
                        <-->



                  1  is "already" sorted







Example of the Quick Sort algorithm

 partition(A,s,e) = partition array elements A[s] .. A[e-1]  using pivot = A[s]


 Steps (recursions) performed by the Quick Sort Algorithm:

        Index --> 0  1  2  3  4  5  6  7 

 Input A[]  =    [5, 4, 1, 7, 2, 9, 3, 6]          Pivot = 5
                  <-------------------->
 partition(A,0,8):          |
                            V
          A[]  = [2, 3, 4, 1, 5, 9, 7, 6]          Pivot = 2
                  <-------->     
 partition(A,0,4):    |
                      V
          A[]  = [1, 2, 4, 3, 5, 9, 7, 6]          Pivot = 4
                        <-->     
 partition(A,2,4):        |
                          V
          A[]  = [1, 2, 3, 4, 5, 9, 7, 6]          Pivot = 9
                                 <----->

                        3  is "already" sorted





Example of the Quick Sort algorithm

 partition(A,s,e) = partition array elements A[s] .. A[e-1]  using pivot = A[s]


 Steps (recursions) performed by the Quick Sort Algorithm:

        Index --> 0  1  2  3  4  5  6  7 

 Input A[]  =    [5, 4, 1, 7, 2, 9, 3, 6]          Pivot = 5
                  <-------------------->
 partition(A,0,8):          |
                            V
          A[]  = [2, 3, 4, 1, 5, 9, 7, 6]          Pivot = 2
                  <-------->     
 partition(A,0,4):    |
                      V
          A[]  = [1, 2, 4, 3, 5, 9, 7, 6]          Pivot = 4
                        <-->     
 partition(A,2,4):        |
                          V
          A[]  = [1, 2, 3, 4, 5, 9, 7, 6]          Pivot = 9
                                 <----->
 partition(A,5,8):                  |
                                    V



 

Example of the Quick Sort algorithm

 partition(A,s,e) = partition array elements A[s] .. A[e-1]  using pivot = A[s]


 Steps (recursions) performed by the Quick Sort Algorithm:

        Index --> 0  1  2  3  4  5  6  7 

 Input A[]  =    [5, 4, 1, 7, 2, 9, 3, 6]          Pivot = 5
                  <-------------------->
 partition(A,0,8):          |
                            V
          A[]  = [2, 3, 4, 1, 5, 9, 7, 6]          Pivot = 2
                  <-------->     
 partition(A,0,4):    |
                      V
          A[]  = [1, 2, 4, 3, 5, 9, 7, 6]          Pivot = 4
                        <-->     
 partition(A,2,4):        |
                          V
          A[]  = [1, 2, 3, 4, 5, 9, 7, 6]          Pivot = 9
                                 <----->
 partition(A,5,8):                  |
                                    V
          A[]  = [1, 2, 3, 4, 5, 7, 6, 9]          Pivot = 7
                                 <-->



Example of the Quick Sort algorithm

 partition(A,s,e) = partition array elements A[s] .. A[e-1]  using pivot = A[s]


 Steps (recursions) performed by the Quick Sort Algorithm:

        Index --> 0  1  2  3  4  5  6  7 

 Input A[]  =    [5, 4, 1, 7, 2, 9, 3, 6]          Pivot = 5
                  <-------------------->
 partition(A,0,8):          |
                            V
          A[]  = [2, 3, 4, 1, 5, 9, 7, 6]          Pivot = 2
                  <-------->     
 partition(A,0,4):    |
                      V
          A[]  = [1, 2, 4, 3, 5, 9, 7, 6]          Pivot = 4
                        <-->    
 partition(A,2,4):        |
                          V
          A[]  = [1, 2, 3, 4, 5, 9, 7, 6]          Pivot = 9
                                 <----->
 partition(A,5,8):                  |
                                    V
          A[]  = [1, 2, 3, 4, 5, 7, 6, 9]          Pivot = 7
                                 <-->
  partition(A,5,7):                |
                                   V
          A[]  = [1, 2, 3, 4, 5, 6, 7, 9]          Done

The Quick Sort Algorithm

  • Let's write the Quick Sort algorithm in Java:

     // Quick Sort: 
     //
     //    sort(A, s, e):  sorts array elements A[s] .. A[e-1]
    
     public static <T extends Comparable<T>> void sort(T[] A, int s, int e)
     {
         if ( e - s <= 1 )       // Base case
             return;             // No need to sort an array of 1 element...
    
         // Partition A using A[s] as pivot
         //
         // partition(A,s,e) returns the index (location) of 
         //                  the pivot element which is the border
         //                  of the 2 subgroups
         int pivotLoc = partition(A, s, e);
    
         sort(A, s, pivotLoc);   // Sort left  half with quick sort
         sort(A, pivotLoc+1, e); // Sort right half with quick sort
     }
    

The Quick Sort Algorithm

  • If the # element in the sub array is ≤ 1, there is no need to sort (it's aleady sorted...):

     // Quick Sort: 
     //
     //    sort(A, s, e):  sorts array elements A[s] .. A[e-1]
    
     public static <T extends Comparable<T>> void sort(T[] A, int s, int e)
     {
         if ( e - s <= 1 )       // Base case
             return;             // No need to sort an array of 1 element...
    
         // Partition A using A[s] as pivot
         //
         // partition(A,s,e) returns the index (location) of 
         //                  the pivot element which is the border
         //                  of the 2 subgroups
         int pivotLoc = partition(A, s, e);
    
         sort(A, s, pivotLoc);   // Sort left  half with quick sort
         sort(A, pivotLoc+1, e); // Sort right half with quick sort
     }
    

The Quick Sort Algorithm

  • Quick Sort first partition the sub array A[s..e-1] using partition(A, s, e):

     // Quick Sort: 
     //
     //    sort(A, s, e):  sorts array elements A[s] .. A[e-1]
    
     public static <T extends Comparable<T>> void sort(T[] A, int s, int e)
     {
         if ( e - s <= 1 )       // Base case
             return;             // No need to sort an array of 1 element...
    
         // Partition sub array A[s..e-1] using A[s] as pivot
         //
         // partition(A, s, e) returns the index (= location) of 
         //                  the pivot element (which is the border
         //                  of the 2 sub arrays/groups)
         int pivotLoc = partition(A, s, e);  // Will be discussed later
    
         sort(A, s, pivotLoc);   // Sort left  half with quick sort
         sort(A, pivotLoc+1, e); // Sort right half with quick sort
     }
    

The Quick Sort Algorithm

  • Then sorts each sub array recursively:

     // Quick Sort: 
     //
     //    sort(A, s, e):  sorts array elements A[s] .. A[e-1]
    
     public static <T extends Comparable<T>> void sort(T[] A, int s, int e)
     {
         if ( e - s <= 1 )       // Base case
             return;             // No need to sort an array of 1 element...
    
         // Partition sub array A[s..e-1] using A[s] as pivot
         //
         // partition(A, s, e) returns the index (= location) of 
         //                  the pivot element (which is the border
         //                  of the 2 sub arrays/groups)
         int pivotLoc = partition(A, s, e);  // Will be discussed later
    
         sort(A, s, pivotLoc);   // Sort left  half with quick sort
         sort(A, pivotLoc+1, e); // Sort right half with quick sort
     }
    

We will study the partition(A, s, e) method in the next slide