Sort Algorithm 4 – Quick Sort

Introduction

Quick Sort is similar to Merge Sort, both of which are divide and conquer techniques, but Quick Sort could be faster. This post explains the concept and implementation of Quick Sort. For concept explanation, I compare between Quick Sort and Merge Sort.

Concepts

The following tables differentiates Quick Sort and Merge Sort

Quick SortMerge Sort
Strategypartition the input array into 2 subarray around a pivotpartition the input array into 2 subarray around the mid point.
Divided method* choose a pivot value.
* loop through the input array, rearrange the items such that:
1) a pivot correct location is found
2) items on the left are less than the pivot, items on the right are more than the pivot.
* identify the midpoint.
* loop through the arrays, makes copy of items to the left subarray, and right subarray.
Conquer methodrecursively partition the original array until the subarray size is 1.recursively partition the original array until the subarray size is 1
How sorting is achievedeach time partition is recursively called, the pivot position is found => item is sorted and placed to correct position in the original arraywhen merging the subarray backs, comparison is made to swap positions betwen subarrays.
Time ComplexityO(nlog n) best case
O(n^2) worst case
O(log n)
Space ComplexityO(1). There is no need to make copies of items from the input array, to allocate subarrays.

The subarrays are identified by left, right boundary
O(n) due to subarrays must be allocated.

Implementation

The following is my code implementation for algorithms:

  • quickSort function calls partition to divide the array.
    • There is no need to allocate space for subarray. The subarray will be identified by left, right boundary.
    • after partition finishes, quickSort further calls itself recursively to partition the left and right array, separated by the pivot's index which is returned by partition.
  • partition function does 2 things:
    • it chooses a pivot value, usually an item at the end of the subarray or right boundary, and performs algorithm such that at the end, the correct position of the pivot in the original array is found.
    • it partitions the original array in to left and right subarray, where all items on the left of the pivot are less than the pivot, and all items on the right are greater than the pivot.
  • the algorithm that finds the pivot correct position and partition the subarray makes use of a pair value. [i,j] where initially i = left, j=left-1.
    • it loops from left to right until i = pivot's index in the input array.
    • it performs necessary swap between items of the input array at i and j index.
    • it returns the correct and sorted position of pivot in the input array as j+1.

The following youtube explains the algorithm with animation

// C++ program for the implementation of merge sort
#include <iostream>
#include <vector>

using namespace std;

// partition the subarray limited by left, right boundary. 
// finding the pivot correct position. 
int partition(vector<int>&vec, int left, int right){
    // chosing pivot as the last element in the subarray
    int pivot = vec[right];
    int i=left, j=left-1;
    // partition the vect into left, right subarray
    // left items < pivot, right items > pivots.
    while (i< right){
        if (vec[i] <= pivot){
            j++; 
            swap(vec[i], vec[j]);   // swaping allowing the partition
        }
        i++;
    }
    // This swap allows placing the pivot at the correct position.
    swap(vec[j+1], vec[right]);
    return j+1; 
}

// quickSort the original vector to smaller subarray, identified by left, right boundary
void quickSort(vector<int>& vec, int left, int right){
    if (right <= left)
        return;
    // Step 1: divide the vector to 2 parts around the pivot
    // also returns the pivot's correct position.    
    int pivotIndex = partition(vec, left, right);
    // Step 2: conquer, continue to divide the left subarray
    // find a pivot correct position
    quickSort(vec, left, pivotIndex -1);
    // Step 3: conquer, continue to divide the left subarray
    // find a pivot correct position
    quickSort(vec, pivotIndex+1, right);
}

int main() {
    vector<int> vec = {12, 11, 13, 5, 6, 7};
    int n = vec.size();

    quickSort (vec, 0, vec.size()-1);

    for (auto i: vec)
        cout << i << " ";
    return 0;
}

Leave a Reply

Your email address will not be published. Required fields are marked *