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.

## 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