Hoare's Partition Algorithm
Last Updated :
11 Nov, 2024
Given an array arr[]
, the task is to partition the array by assuming first element as pivot element.
The partition of an array must satisfy the following two conditions:
- Elements smaller than pivot element must appear at index less than or equal to partition index.
- Elements larger than or equal to pivot element must appear at index greater than partition index.
Partition index is equal to count of elements, strictly smaller than pivot, minus one.
Note: There might me more than one possible partition arrays.
Examples:
Input: arr[] = [5, 3, 8, 4, 2, 7, 1, 10]
Output: [1, 3, 2, 4, 8, 7, 5, 10]
Explanation: The partition index is 3 and pivot element is 5, all elements smaller than pivot element [1, 3, 2, 4] were arranged before partition index and elements larger than or equal to pivot [13, 9, 12, 11] were arranged after partition index.
Input: arr[] = [12, 10, 9, 16, 19, 9]
Output: [9, 10, 9, 16, 19, 12]
Explanation: The partition index is 2 and pivot element is 12, all elements smaller than pivot element [9, 10, 9] were arranged before or at partition index and elements larger than or equal to pivot [16, 19, 12] were arranged after partition index.
Hoare's Algorithm for Array Partition
Hoare's partitioning algorithm is an efficient way to partition an array around a pivot. It’s based on two pointers that start at opposite ends of the array and move toward each other until they find elements that need to be swapped.
Step-by-step explanation of algorithm:
- Consider the first element as the pivot and initialise two pointers,
i
at the start and j
at the end of the array. - Move
i
to the right until an element greater than or equal to the pivot is found, and move j
to the left until an element less than or equal to the pivot is found. - If
i
points to an element greater than or equal to the pivot and j
points to an element less than or equal to the pivot, swap them. - Repeat the process, moving
i
and j
toward each other until they meet or cross. - When the pointers cross, the partitioning is complete, with elements less than or equal to the pivot on the left and those greater than or equal to the pivot on the right.
C++
// C++ program to partition the array
// using Hoare's Partition Algorithm
#include <iostream>
#include <vector>
using namespace std;
// Function to partition the array according
// to pivot index element
void partition(vector<int> &arr) {
int n = arr.size();
int pivot = arr[0];
int i = -1, j = n;
while (true) {
// find next element larger than pivot
// from the left
do {
i++;
} while (arr[i] < pivot);
// find next element smaller than pivot
// from the right
do {
j--;
} while (arr[j] > pivot);
// if left and right crosses each other
// no swapping required
if (i > j) break;
// swap larger and smaller elements
swap(arr[i], arr[j]);
}
}
int main() {
vector<int> arr = {5, 3, 8, 4, 2, 7, 1, 10};
partition(arr);
for (int i = 0; i < arr.size(); i++)
cout << arr[i] << " ";
return 0;
}
C
// C program to partition the array
// using Hoare's Partition Algorithm
#include <stdio.h>
#include <stdlib.h>
// Function to partition the array according
// to pivot index element
void partition(int arr[], int n) {
int pivot = arr[0];
int i = -1, j = n;
while (1) {
// find next element larger than pivot
// from the left
do {
i++;
} while (arr[i] < pivot);
// find next element smaller than pivot
// from the right
do {
j--;
} while (arr[j] > pivot);
// if left and right crosses each other
// no swapping required
if (i > j) break;
// swap larger and smaller elements
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int main() {
int arr[] = {5, 3, 8, 4, 2, 7, 1, 10};
int n = sizeof(arr) / sizeof(arr[0]);
partition(arr, n);
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
return 0;
}
Java
// Java program to partition the array
// using Hoare's Partition Algorithm
import java.util.Arrays;
class GfG {
// Function to partition the array according
// to pivot index element
static void partition(int[] arr) {
int n = arr.length;
int pivot = arr[0];
int i = -1, j = n;
while (true) {
// find next element larger than pivot
// from the left
do {
i++;
} while (arr[i] < pivot);
// find next element smaller than pivot
// from the right
do {
j--;
} while (arr[j] > pivot);
// if left and right crosses each other
// no swapping required
if (i > j) break;
// swap larger and smaller elements
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
public static void main(String[] args) {
int[] arr = {5, 3, 8, 4, 2, 7, 1, 10};
partition(arr);
for (int ele: arr)
System.out.print(ele + " ");
}
}
Python
# Python program to partition the array
# using Hoare's Partition Algorithm
# Function to partition the array according to pivot index element
def partition(arr):
n = len(arr)
pivot = arr[0]
i = -1
j = n
while True:
# find next element larger than pivot from the left
while True:
i += 1
if arr[i] >= pivot:
break
# find next element smaller than pivot from the right
while True:
j -= 1
if arr[j] <= pivot:
break
# if left and right crosses each other no swapping required
if i > j:
break
# swap larger and smaller elements
arr[i], arr[j] = arr[j], arr[i]
if __name__ == "__main__":
arr = [5, 3, 8, 4, 2, 7, 1, 10]
partition(arr)
for num in arr:
print(num, end=' ')
C#
// C# program to partition the array
// using Hoare's Partition Algorithm
using System;
class GfG {
// Function to partition the array according
// to pivot index element
static void partition(int[] arr) {
int n = arr.Length;
int pivot = arr[0];
int i = -1, j = n;
while (true) {
// find next element larger than pivot
// from the left
do {
i++;
} while (arr[i] < pivot);
// find next element smaller than pivot
// from the right
do {
j--;
} while (arr[j] > pivot);
// if left and right crosses each other
// no swapping required
if (i > j) break;
// swap larger and smaller elements
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
static void Main() {
int[] arr = {5, 3, 8, 4, 2, 7, 1, 10};
partition(arr);
Console.WriteLine(string.Join(" ", arr));
}
}
JavaScript
// JavaScript program to partition the array
// using Hoare's Partition Algorithm
function partition(arr) {
let n = arr.length;
let pivot = arr[0];
let i = -1, j = n;
while (true) {
// find next element larger than pivot
// from the left
do {
i++;
} while (arr[i] < pivot);
// find next element smaller than pivot
// from the right
do {
j--;
} while (arr[j] > pivot);
// if left and right crosses each other
// no swapping required
if (i > j) break;
// swap larger and smaller elements
[arr[i], arr[j]] = [arr[j], arr[i]];
}
}
// Driver Code
let arr = [5, 3, 8, 4, 2, 7, 1, 10];
partition(arr);
console.log(arr.join(' '));
Time Complexity: O(n)
Auxiliary Space: O(1)
Some Interesting Facts
- Hoare's Partition Algorithm is generally faster than Lomuto's because it performs fewer swaps and makes only one traversal of the array, leading to better time complexity in practice.
- It works in-place and does not require extra space, unlike the naive partitioning method which uses a temporary array.
- It can be used to implement a stable version of Quick Sort with the right adjustments, though it is not inherently stable.
- We can easily modify the algorithm to consider the first element (or any other element) as pivot by swapping first and last elements and then using the same code.
Similar Reads
Naive Partition Algorithm Given an array arr[], the task is to partition the array by assuming last element as pivot element. The partition of an array must satisfy the following two conditions:Elements smaller than or equal to the pivot element appear before pivot in the array.Elements larger than the pivot element appear a
7 min read
Lomuto Partition Algorithm Given an array arr[], the task is to partition the array by assuming last element as pivot element. The partition of an array must satisfy the following two conditions:Elements smaller than the pivot element appear before pivot in the array.Elements larger than or equal to the pivot element appear a
7 min read
Partition Algorithms - Complete Tutorial Partition algorithms are key techniques in computer science, widely used in sorting (like QuickSort) and selection problems. By dividing an array around a pivot, they allow data to be organized into segments for faster sorting and searching. This tutorial covers popular partitioning methods, includi
3 min read
Preparata Algorithm Preparata's algorithm is a recursive Divide and Conquer Algorithm where the rank of each input key is computed and the keys are outputted according to their ranks. C++ m[i, j] := M[i, j] for 1 <= i, j <= n in parallel; for r : = 1 to logn do { Step 1. In parallel set q[i, j, k] := m[i, j] + m[
14 min read
Generate all partition of a set Given a set A = {1, 2, 3, . . ., n }. It is called a partition of the set A if the following conditions follow: The union of all the sets is the set AThe intersection of any two sets is an empty setExamples: Input: n = 3Output: [{1, 2, 3}], [{1, 2}, {3}], [{1, 3}, {2}], [{1}, {2, 3}], [{1}, {2}, {3}
8 min read