Skip to main content

Quick Sort

This page provides introduction to Quick Sort.

Overview

Quick Sort is a divide-and-conquer algorithm that partitions the array into two halves around a pivot element. Elements smaller than the pivot go to its left, and larger ones go to its right. It then recursively sorts the left and right subarrays.

Let's sort array below, with quick sort:

[1,8,3,9,4,5,7][1, 8, 3, 9, 4, 5, 7]

Partition the whole array using the last element, 77, as the pivot. After partitioning, all elements smaller than 77 will be positioned on its left, and all elements greater than 77 will be on its right.

Assign pointer lt, gt and pivot pointers.

quick-sort-1.svg

In above array image, element 11 at gt pointer is less than pivot element 77:

  • Increment lt pointer.
  • Swap elements at lt and gt pointers, which is same in this case.
quick-sort-2.svg

Increment gt pointer.

quick-sort-3.svg

In above array image, element 88 at gt pointer is greater than pivot element 77:

  • lt pointer remains the same.
  • No swap is needed.
  • Increment gt pointer.
quick-sort-4.svg

In above array image, element 33 at gt pointer is less than pivot element 77:

  • Increment lt pointer
  • Swap elements at lt and gt pointers.
quick-sort-5.svg

Increment gt pointer.

quick-sort-6.svg

In above array image, element 99 at gt pointer is greater than pivot element 77:

  • lt pointer remains the same.
  • No swap is needed.
  • Increment gt pointer.
quick-sort-7.svg

In above array image, element 44 at gt pointer is less than pivot element 77:

  • Increment lt pointer
  • Swap elements at lt and gt pointers.
quick-sort-8.svg

Increment gt pointer.

quick-sort-9.svg

In above array image, element 99 at gt pointer is greater than pivot 77:

  • lt pointer remains the same.
  • No swap is needed.
  • Increment gt pointer.
quick-sort-10.svg

Since now, gt equals pivot pointer we exit the for loop and swap elements at lt + 1 and pivot pointers to place pivot element 77 at it's correct position.

quick-sort-11.svg

This concludes the partitioning of the whole array around the pivot element 77. We apply the same partitioning process recursively on the left and right subarrays of the pivot element 77 to get the sorted array as below:

quick-sort-12.svg
public void quickSort(int[] arr, int lo, int hi) {
if(lo < hi) {
int pivot = partition(arr, lo, hi);
quickSort(arr, lo, pivot);
quickSort(arr, pivot + 1, hi);
}
}

public int partition(int[] arr, int lo, int hi) {
pivot = arr[hi];

int lt = lo - 1; // pointer to elements smaller than pivot
for(int gt = lo; gt < hi; gt++) { // pointer to elements greater than pivot
if(arr[gt] < pivot) {
lt = lt + 1;
int temp = arr[lt];
arr[lt] = arr[gt];
arr[gt] = temp;
}
}

int temp = arr[lt + 1];
arr[lt + 1] = arr[hi];
arr[hi] = temp;

return lt + 1;
}

Complexity

Let's say there are N\text{N} elements in an array.

Time Complexity

The average case time complexity of Quicksort is:

O(NlogN)\text{O}(\text{N} \log \text{N})

However, when the pivot choice consistently results in unbalanced partitions complexity becomes:

O(N2)\text{O}(\text{N}^2)
info

To mitigate this, randomized pivot selection is commonly used.

Space Complexity

The average case space complexity of quicksort is:

O(NlogN)\text{O}(\text{N} \log \text{N})

Leetcode Problem Set