Hoare's Partition Algorithm (original) (raw)
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, allelements 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, allelements 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.
Table of Content
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 movej
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
andj
**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 #include using namespace std;
// Function to partition the array according // to pivot index element void partition(vector &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 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.