Related Articles

# 3-Way QuickSort (Dutch National Flag)

• Difficulty Level : Hard
• Last Updated : 31 May, 2021

In simple QuickSort algorithm, we select an element as pivot, partition the array around a pivot and recur for subarrays on the left and right of the pivot.
Consider an array which has many redundant elements. For example, {1, 4, 2, 4, 2, 4, 1, 2, 4, 1, 2, 2, 2, 2, 4, 1, 4, 4, 4}. If 4 is picked as a pivot in Simple Quick Sort, we fix only one 4 and recursively process remaining occurrences.
The idea of 3 way Quick Sort is to process all occurrences of the pivot and is based on Dutch National Flag algorithm.

```In 3 Way QuickSort, an array arr[l..r] is divided in 3 parts:
a) arr[l..i] elements less than pivot.
b) arr[i+1..j-1] elements equal to pivot.
c) arr[j..r] elements greater than pivot.```

Below is the implementation of the above algorithm.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

## C++

 `// C++ program for 3-way quick sort``#include ``using` `namespace` `std;` `/* This function partitions a[] in three parts``   ``a) a[l..i] contains all elements smaller than pivot``   ``b) a[i+1..j-1] contains all occurrences of pivot``   ``c) a[j..r] contains all elements greater than pivot */``void` `partition(``int` `a[], ``int` `l, ``int` `r, ``int``& i, ``int``& j)``{``    ``i = l - 1, j = r;``    ``int` `p = l - 1, q = r;``    ``int` `v = a[r];` `    ``while` `(``true``) {``        ``// From left, find the first element greater than``        ``// or equal to v. This loop will definitely``        ``// terminate as v is last element``        ``while` `(a[++i] < v)``            ``;` `        ``// From right, find the first element smaller than``        ``// or equal to v``        ``while` `(v < a[--j])``            ``if` `(j == l)``                ``break``;` `        ``// If i and j cross, then we are done``        ``if` `(i >= j)``            ``break``;` `        ``// Swap, so that smaller goes on left greater goes``        ``// on right``        ``swap(a[i], a[j]);` `        ``// Move all same left occurrence of pivot to``        ``// beginning of array and keep count using p``        ``if` `(a[i] == v) {``            ``p++;``            ``swap(a[p], a[i]);``        ``}` `        ``// Move all same right occurrence of pivot to end of``        ``// array and keep count using q``        ``if` `(a[j] == v) {``            ``q--;``            ``swap(a[j], a[q]);``        ``}``    ``}` `    ``// Move pivot element to its correct index``    ``swap(a[i], a[r]);` `    ``// Move all left same occurrences from beginning``    ``// to adjacent to arr[i]``    ``j = i - 1;``    ``for` `(``int` `k = l; k < p; k++, j--)``        ``swap(a[k], a[j]);` `    ``// Move all right same occurrences from end``    ``// to adjacent to arr[i]``    ``i = i + 1;``    ``for` `(``int` `k = r - 1; k > q; k--, i++)``        ``swap(a[i], a[k]);``}` `// 3-way partition based quick sort``void` `quicksort(``int` `a[], ``int` `l, ``int` `r)``{``    ``if` `(r <= l)``        ``return``;` `    ``int` `i, j;` `    ``// Note that i and j are passed as reference``    ``partition(a, l, r, i, j);` `    ``// Recur``    ``quicksort(a, l, j);``    ``quicksort(a, i, r);``}` `// A utility function to print an array``void` `printarr(``int` `a[], ``int` `n)``{``    ``for` `(``int` `i = 0; i < n; ++i)``        ``printf``(``"%d  "``, a[i]);``    ``printf``(``"\n"``);``}` `// Driver code``int` `main()``{``    ``int` `a[] = { 4, 9, 4, 4, 1, 9, 4, 4, 9, 4, 4, 1, 4 };``    ``int` `size = ``sizeof``(a) / ``sizeof``(``int``);``  ` `      ``// Function Call``    ``printarr(a, size);``    ``quicksort(a, 0, size - 1);``    ``printarr(a, size);``    ``return` `0;``}`

## Java

 `// Java program for 3-way quick sort``import` `java.util.*;``class` `GFG``{` `    ``static` `int` `i, j;``    ` `/* This function partitions a[] in three parts``   ``a) a[l..i] contains all elements smaller than pivot``   ``b) a[i+1..j-1] contains all occurrences of pivot``   ``c) a[j..r] contains all elements greater than pivot */``static` `void` `partition(``int` `a[], ``int` `l, ``int` `r)``{``  ` `    ``i = l - ``1``; j = r;``    ``int` `p = l - ``1``, q = r;``    ``int` `v = a[r];` `    ``while` `(``true``)``    ``{``      ` `        ``// From left, find the first element greater than``        ``// or equal to v. This loop will definitely``        ``// terminate as v is last element``        ``while` `(a[++i] < v)``            ``;` `        ``// From right, find the first element smaller than``        ``// or equal to v``        ``while` `(v < a[--j])``            ``if` `(j == l)``                ``break``;` `        ``// If i and j cross, then we are done``        ``if` `(i >= j)``            ``break``;` `        ``// Swap, so that smaller goes on left greater goes``        ``// on right``        ``int` `temp = a[i];``          ``a[i] = a[j];``          ``a[j] = temp;` `        ``// Move all same left occurrence of pivot to``        ``// beginning of array and keep count using p``        ``if` `(a[i] == v) {``            ``p++;``            ``temp = a[i];``            ``a[i] = a[p];``            ``a[p] = temp;` `        ``}` `        ``// Move all same right occurrence of pivot to end of``        ``// array and keep count using q``        ``if` `(a[j] == v) {``            ``q--;``            ``temp = a[q];``            ``a[q] = a[j];``            ``a[j] = temp;``        ``}``    ``}` `    ``// Move pivot element to its correct index``    ``int` `temp = a[i];``      ``a[i] = a[r];``      ``a[r] = temp;``  ` `    ``// Move all left same occurrences from beginning``    ``// to adjacent to arr[i]``    ``j = i - ``1``;``    ``for` `(``int` `k = l; k < p; k++, j--)``    ``{``        ``temp = a[k];``          ``a[k] = a[j];``          ``a[j] = temp;``    ``}``  ` `    ``// Move all right same occurrences from end``    ``// to adjacent to arr[i]``    ``i = i + ``1``;``    ``for` `(``int` `k = r - ``1``; k > q; k--, i++)``    ``{``        ``temp = a[i];``          ``a[i] = a[k];``          ``a[k] = temp;``    ``}``}` `// 3-way partition based quick sort``static` `void` `quicksort(``int` `a[], ``int` `l, ``int` `r)``{``    ``if` `(r <= l)``        ``return``;` `   ``i = ``0``; j = ``0``;` `    ``// Note that i and j are passed as reference``    ``partition(a, l, r);` `    ``// Recur``    ``quicksort(a, l, j);``    ``quicksort(a, i, r);``}` `// A utility function to print an array``static` `void` `printarr(``int` `a[], ``int` `n)``{``    ``for` `(``int` `i = ``0``; i < n; ++i)``        ``System.out.printf(``"%d  "``, a[i]);``    ``System.out.printf(``"\n"``);``}` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``int` `a[] = { ``4``, ``9``, ``4``, ``4``, ``1``, ``9``, ``4``, ``4``, ``9``, ``4``, ``4``, ``1``, ``4` `};``    ``int` `size = a.length;``  ` `      ``// Function Call``    ``printarr(a, size);``    ``quicksort(a, ``0``, size - ``1``);``    ``printarr(a, size);``}``}` `// This code is contributed by Rajput-Ji`

## C#

 `// C# program for 3-way quick sort``using` `System;` `class` `GFG {``    ``// A function which is used to swap values``    ``static` `void` `swap(``ref` `T lhs, ``ref` `T rhs)``    ``{``        ``T temp;``        ``temp = lhs;``        ``lhs = rhs;``        ``rhs = temp;``    ``}``    ``/* This function partitions a[] in three parts``       ``a) a[l..i] contains all elements smaller than pivot``       ``b) a[i+1..j-1] contains all occurrences of pivot``       ``c) a[j..r] contains all elements greater than pivot``     ``*/``    ``public` `static` `void` `partition(``int``[] a, ``int` `l, ``int` `r,``                                 ``ref` `int` `i, ``ref` `int` `j)``    ``{``        ``i = l - 1;``        ``j = r;``        ``int` `p = l - 1, q = r;``        ``int` `v = a[r];` `        ``while` `(``true``) {``            ``// From left, find the first element greater``            ``// than or equal to v. This loop will definitely``            ``// terminate as v is last element``            ``while` `(a[++i] < v)``                ``;` `            ``// From right, find the first element smaller``            ``// than or equal to v``            ``while` `(v < a[--j])``                ``if` `(j == l)``                    ``break``;` `            ``// If i and j cross, then we are done``            ``if` `(i >= j)``                ``break``;` `            ``// Swap, so that smaller goes on left greater``            ``// goes on right``            ``swap(``ref` `a[i], ``ref` `a[j]);` `            ``// Move all same left occurrence of pivot to``            ``// beginning of array and keep count using p``            ``if` `(a[i] == v) {``                ``p++;``                ``swap(``ref` `a[p], ``ref` `a[i]);``            ``}` `            ``// Move all same right occurrence of pivot to``            ``// end of array and keep count using q``            ``if` `(a[j] == v) {``                ``q--;``                ``swap(``ref` `a[j], ``ref` `a[q]);``            ``}``        ``}` `        ``// Move pivot element to its correct index``        ``swap(``ref` `a[i], ``ref` `a[r]);` `        ``// Move all left same occurrences from beginning``        ``// to adjacent to arr[i]``        ``j = i - 1;``        ``for` `(``int` `k = l; k < p; k++, j--)``            ``swap(``ref` `a[k], ``ref` `a[j]);` `        ``// Move all right same occurrences from end``        ``// to adjacent to arr[i]``        ``i = i + 1;``        ``for` `(``int` `k = r - 1; k > q; k--, i++)``            ``swap(``ref` `a[i], ``ref` `a[k]);``    ``}` `    ``// 3-way partition based quick sort``    ``public` `static` `void` `quicksort(``int``[] a, ``int` `l, ``int` `r)``    ``{``        ``if` `(r <= l)``            ``return``;` `        ``int` `i = 0, j = 0;` `        ``// Note that i and j are passed as reference``        ``partition(a, l, r, ``ref` `i, ``ref` `j);` `        ``// Recur``        ``quicksort(a, l, j);``        ``quicksort(a, i, r);``    ``}` `    ``// A utility function to print an array``    ``public` `static` `void` `printarr(``int``[] a, ``int` `n)``    ``{``        ``for` `(``int` `i = 0; i < n; ++i)``            ``Console.Write(a[i] + ``" "``);``        ``Console.Write(``"\n"``);``    ``}` `    ``// Driver code``    ``static` `void` `Main()``    ``{``        ``int``[] a = { 4, 9, 4, 4, 1, 9, 4, 4, 9, 4, 4, 1, 4 };``        ``int` `size = a.Length;``        ` `          ``// Function Call``          ``printarr(a, size);``        ``quicksort(a, 0, size - 1);``        ``printarr(a, size);``    ``}``    ``// This code is contributed by DrRoot_``}`

## Javascript

 ``
Output

```4  9  4  4  1  9  4  4  9  4  4  1  4
1  1  4  4  4  4  4  4  4  4  9  9  9  ```

Thanks to Utkarsh for suggesting above implementation.

Another Implementation using Dutch National Flag Algorithm

## C++

 `// C++ program for 3-way quick sort``#include ``using` `namespace` `std;` `void` `swap(``int``* a, ``int``* b)``{``    ``int` `temp = *a;``    ``*a = *b;``    ``*b = temp;``}` `// A utility function to print an array``void` `printarr(``int` `a[], ``int` `n)``{``    ``for` `(``int` `i = 0; i < n; ++i)``        ``printf``(``"%d "``, a[i]);``    ``printf``(``"\n"``);``}` `/* This function partitions a[] in three parts``a) a[l..i] contains all elements smaller than pivot``b) a[i+1..j-1] contains all occurrences of pivot``c) a[j..r] contains all elements greater than pivot */` `// It uses Dutch National Flag Algorithm``void` `partition(``int` `a[], ``int` `low, ``int` `high, ``int``& i, ``int``& j)``{``    ``// To handle 2 elements``    ``if` `(high - low <= 1) {``        ``if` `(a[high] < a[low])``            ``swap(&a[high], &a[low]);``        ``i = low;``        ``j = high;``        ``return``;``    ``}` `    ``int` `mid = low;``    ``int` `pivot = a[high];``    ``while` `(mid <= high) {``        ``if` `(a[mid] < pivot)``            ``swap(&a[low++], &a[mid++]);``        ``else` `if` `(a[mid] == pivot)``            ``mid++;``        ``else` `if` `(a[mid] > pivot)``            ``swap(&a[mid], &a[high--]);``    ``}` `    ``// update i and j``    ``i = low - 1;``    ``j = mid; ``// or high+1``}` `// 3-way partition based quick sort``void` `quicksort(``int` `a[], ``int` `low, ``int` `high)``{``    ``if` `(low >= high) ``// 1 or 0 elements``        ``return``;` `    ``int` `i, j;` `    ``// Note that i and j are passed as reference``    ``partition(a, low, high, i, j);` `    ``// Recur two halves``    ``quicksort(a, low, i);``    ``quicksort(a, j, high);``}` `// Driver Code``int` `main()``{``    ``int` `a[] = { 4, 9, 4, 4, 1, 9, 4, 4, 9, 4, 4, 1, 4 };``    ``// int a[] = {4, 39, 54, 14, 31, 89, 44, 34, 59, 64, 64,``    ``// 11, 41}; int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};``    ``// int a[] = {91, 82, 73, 64, 55, 46, 37, 28, 19, 10};``    ``// int a[] = {4, 9, 4, 4, 9, 1, 1, 1};``    ``int` `size = ``sizeof``(a) / ``sizeof``(``int``);` `    ``// Function Call``    ``printarr(a, size);``    ``quicksort(a, 0, size - 1);``    ``printarr(a, size);``    ``return` `0;``}`

## C#

 `// C# program for 3-way quick sort``using` `System;` `class` `GFG {``    ``// A function which is used to swap values``    ``static` `void` `swap(``ref` `T lhs, ``ref` `T rhs)``    ``{``        ``T temp;``        ``temp = lhs;``        ``lhs = rhs;``        ``rhs = temp;``    ``}` `    ``// A utility function to print an array``    ``public` `static` `void` `printarr(``int``[] a, ``int` `n)``    ``{``        ``for` `(``int` `i = 0; i < n; ++i)``            ``Console.Write(a[i] + ``" "``);``        ``Console.Write(``"\n"``);``    ``}` `    ``/* This function partitions a[] in three parts``    ``a) a[l..i] contains all elements smaller than pivot``    ``b) a[i+1..j-1] contains all occurrences of pivot``    ``c) a[j..r] contains all elements greater than pivot */` `    ``// It uses Dutch National Flag Algorithm``    ``public` `static` `void` `partition(``int``[] a, ``int` `low, ``int` `high,``                                 ``ref` `int` `i, ``ref` `int` `j)``    ``{``        ``// To handle 2 elements``        ``if` `(high - low <= 1) {``            ``if` `(a[high] < a[low])``                ``swap(``ref` `a[high], ``ref` `a[low]);``            ``i = low;``            ``j = high;``            ``return``;``        ``}` `        ``int` `mid = low;``        ``int` `pivot = a[high];``        ``while` `(mid <= high) {``            ``if` `(a[mid] < pivot)``                ``swap(``ref` `a[low++], ``ref` `a[mid++]);``            ``else` `if` `(a[mid] == pivot)``                ``mid++;``            ``else` `if` `(a[mid] > pivot)``                ``swap(``ref` `a[mid], ``ref` `a[high--]);``        ``}` `        ``// update i and j``        ``i = low - 1;``        ``j = mid; ``// or high+1``    ``}` `    ``// 3-way partition based quick sort``    ``public` `static` `void` `quicksort(``int``[] a, ``int` `low, ``int` `high)``    ``{``        ``if` `(low >= high) ``// 1 or 0 elements``            ``return``;` `        ``int` `i = 0, j = 0;` `        ``// Note that i and j are passed as reference``        ``partition(a, low, high, ``ref` `i, ``ref` `j);` `        ``// Recur two halves``        ``quicksort(a, low, i);``        ``quicksort(a, j, high);``    ``}` `    ``// Driver code``    ``static` `void` `Main()``    ``{``        ``int``[] a = { 4, 9, 4, 4, 1, 9, 4, 4, 9, 4, 4, 1, 4 };``        ``// int[] a = {4, 39, 54, 14, 31, 89, 44, 34, 59, 64,``        ``// 64, 11, 41}; int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9,``        ``// 10}; int[] a = {91, 82, 73, 64, 55, 46, 37, 28,``        ``// 19, 10}; int[] a = {4, 9, 4, 4, 9, 1, 1, 1};``        ``int` `size = a.Length;``        ` `          ``// Function Call``        ``printarr(a, size);``        ``quicksort(a, 0, size - 1);``        ``printarr(a, size);``    ``}``    ``// This code is contributed by DrRoot_``}`
Output
```4 9 4 4 1 9 4 4 9 4 4 1 4
1 1 4 4 4 4 4 4 4 4 9 9 9 ```

Thanks Aditya Goel for this implementation.
Reference:
http://algs4.cs.princeton.edu/lectures/23DemoPartitioning.pdf
http://www.sorting-algorithms.com/quick-sort-3-way