Cycle Sort is an in-place, unstable, comparison-based sorting algorithm that is optimal in terms of the minimum number of memory writes.
- The idea is to divide the array into cycles, where each cycle consists of elements that belong to each other’s correct positions, and then rotate these cycles to place all elements correctly.
- In Cycle Sort, each element is written at most once to its correct position, making it useful in situations where write operations are costly.
Example:
Input: arr[] = [2, 4, 5, 1, 3]
Output: [1,2,3,4,5]
Explanation:
- 2 -> correct index 1
- 4 -> correct index 3
- 5 -> correct index 4
- 1 -> correct index 0
- 3 -> correct index 2
These form cycles: Cycle 1: 2 -> 4 -> 1 -> 2 , Cycle 2: 5 -> 3 -> 5. After rotating these cycles, array becomes: [1, 2, 3, 4, 5]
Cycle Sort Approach - O(n^2) Time O(1) Space
The main idea is simple:
For every element, count how many elements are smaller than it.
This count gives its correct position in the sorted array.
If the element is not already at its correct position, place it there.
While placing, another element gets displaced -repeat the same process for that element.
This continues until we come back to the starting point, forming a cycle.
using namespace std;
// Function sort the array using Cycle sort
void cycleSort(vector<int> &arr)
{
int n = arr.size();
// traverse array elements and put it to on
// the right place
for (int cycle_start = 0; cycle_start <= n - 2; cycle_start++) {
// initialize item as starting point
int item = arr[cycle_start];
// Find position where we put the item. We basically
// count all smaller elements on right side of item.
int pos = cycle_start;
for (int i = cycle_start + 1; i < n; i++)
if (arr[i] < item)
pos++;
// If item is already in correct position
if (pos == cycle_start)
continue;
// ignore all duplicate elements
while (item == arr[pos])
pos += 1;
// put the item to its right position
if (pos != cycle_start) {
swap(item, arr[pos]);
}
// Rotate rest of the cycle
while (pos != cycle_start) {
pos = cycle_start;
// Find position where we put the element
for (int i = cycle_start + 1; i < n; i++)
if (arr[i] < item)
pos += 1;
// ignore all duplicate elements
while (item == arr[pos])
pos += 1;
// put the item to it's right position
if (item != arr[pos]) {
swap(item, arr[pos]);
}
}
}
}
int main()
{
vector<int> arr = {3,5,2,1,4};
int n = arr.size();
cycleSort(arr);
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
class GFG {
// Function sort the array using Cycle sort
public static void cycleSort(int arr[])
{
int n = arr.length;
// traverse array elements and put it to on
// the right place
for (int cycle_start = 0; cycle_start <= n - 2;
cycle_start++) {
// initialize item as starting point
int item = arr[cycle_start];
// Find position where we put the item. We
// basically count all smaller elements on right
// side of item.
int pos = cycle_start;
for (int i = cycle_start + 1; i < n; i++)
if (arr[i] < item)
pos++;
// If item is already in correct position
if (pos == cycle_start)
continue;
// ignore all duplicate elements
while (item == arr[pos])
pos += 1;
// put the item to it's right position
if (pos != cycle_start) {
int temp = item;
item = arr[pos];
arr[pos] = temp;
}
// Rotate rest of the cycle
while (pos != cycle_start) {
pos = cycle_start;
// Find position where we put the element
for (int i = cycle_start + 1; i < n; i++)
if (arr[i] < item)
pos += 1;
// ignore all duplicate elements
while (item == arr[pos])
pos += 1;
// put the item to it's right position
if (item != arr[pos]) {
int temp = item;
item = arr[pos];
arr[pos] = temp;
}
}
}
}
public static void main(String[] args)
{
int arr[] = {3,5,2,1,4};
int n = arr.length;
cycleSort(arr);
for (int i = 0; i < n; i++)
System.out.print(arr[i] + " ");
}
}
# Function to sort the array using Cycle Sort
def cycleSort(arr):
n = len(arr)
# traverse array elements and put it to on the right place
for cycle_start in range(0, n - 1):
# initialize item as starting point
item = arr[cycle_start]
# Find position where we put the item.
# We basically count all smaller elements on right side of item.
pos = cycle_start
for i in range(cycle_start + 1, n):
if arr[i] < item:
pos += 1
# If item is already in correct position
if pos == cycle_start:
continue
# ignore all duplicate elements
while item == arr[pos]:
pos += 1
# put the item to its right position
if pos != cycle_start:
arr[pos], item = item, arr[pos]
# Rotate rest of the cycle
while pos != cycle_start:
pos = cycle_start
# Find position where we put the element
for i in range(cycle_start + 1, n):
if arr[i] < item:
pos += 1
# ignore duplicates
while item == arr[pos]:
pos += 1
# put the item to its right position
if item != arr[pos]:
arr[pos], item = item, arr[pos]
if __name__ == "__main__":
arr = [3,5,2,1,4]
n = len(arr)
cycleSort(arr)
for x in arr:
print(x, end=" ")
using System;
class GFG {
// Function sort the array using Cycle sort
public static void cycleSort(int[] arr)
{
int n = arr.Length;
// traverse array elements and put it to on the right place
for (int cycle_start = 0; cycle_start <= n - 2; cycle_start++) {
// initialize item as starting point
int item = arr[cycle_start];
// Find position where we put the item.
// We basically count all smaller elements on right side of item.
int pos = cycle_start;
for (int i = cycle_start + 1; i < n; i++)
if (arr[i] < item)
pos++;
// If item is already in correct position
if (pos == cycle_start)
continue;
// ignore all duplicate elements
while (item == arr[pos])
pos += 1;
// put the item to it's right position
if (pos != cycle_start) {
int temp = item;
item = arr[pos];
arr[pos] = temp;
}
// Rotate rest of the cycle
while (pos != cycle_start) {
pos = cycle_start;
// Find position where we put the element
for (int i = cycle_start + 1; i < n; i++)
if (arr[i] < item)
pos += 1;
// ignore all duplicate elements
while (item == arr[pos])
pos += 1;
// put the item to it's right position
if (item != arr[pos]) {
int temp = item;
item = arr[pos];
arr[pos] = temp;
}
}
}
}
public static void Main()
{
int[] arr = {3,5,2,1,4};
int n = arr.Length;
cycleSort(arr);
for (int i = 0; i < n; i++)
Console.Write(arr[i] + " ");
}
}
// Function to sort the array using Cycle Sort
function cycleSort(arr) {
const n = arr.length;
// traverse array elements and put it to on the right place
for (let cycle_start = 0; cycle_start <= n - 2; cycle_start++) {
// initialize item as starting point
let item = arr[cycle_start];
// Find position where we put the item.
// We basically count all smaller elements on right side of item.
let pos = cycle_start;
for (let i = cycle_start + 1; i < n; i++) {
if (arr[i] < item) {
pos++;
}
}
// If item is already in correct position
if (pos === cycle_start) continue;
// Ignore duplicates
while (item === arr[pos]) {
pos += 1;
}
// Put the item to its correct position
if (pos !== cycle_start) {
let temp = item;
item = arr[pos];
arr[pos] = temp;
}
// Rotate rest of the cycle
while (pos !== cycle_start) {
pos = cycle_start;
// Find position where we put the item
for (let i = cycle_start + 1; i < n; i++) {
if (arr[i] < item) {
pos += 1;
}
}
// Ignore duplicates
while (item === arr[pos]) {
pos += 1;
}
// Put the item to its correct position
if (item !== arr[pos]) {
let temp = item;
item = arr[pos];
arr[pos] = temp;
}
}
}
}
// Driver code
const arr = [3,5,2,1,4];
const n = arr.length;
cycleSort(arr);
let result = "";
for (let i = 0; i < n; i++) {
result += arr[i] + " ";
}
console.log(result.trim());
Output
1 2 3 4 5
Cycle Sort for Range [1…N] or [0…N] - O(n) Time O(1) Space
This method is a special optimized version of Cycle Sort that works only when array elements are in the range 1 to N or 0 to N. In this case, we do not need to explicitly detect cycles; instead, we directly place elements at their correct indices using swapping.
If elements are in range 1 to N, then: Correct index of an element = value - 1
Example: 1 -> index 0, 2 -> index 1, …, N -> index N-1
If elements are in range 0 to N, then: Correct index of an element = value itself
using namespace std;
// Function to perform Cycle Sort
void cycleSort(vector<int> &arr) {
int n = arr.size();
int i = 0;
// Traverse array
while (i < n) {
// Correct index of current element
int correct = arr[i] - 1;
// If element is not at correct position, swap
if (arr[i] != arr[correct]) {
swap(arr[i], arr[correct]);
}
// Otherwise move to next index
else {
i++;
}
}
}
int main() {
vector<int> arr = {3, 2, 4, 5, 1};
int n = arr.size();
cycleSort(arr);
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
class GFG {
// Function to perform Cycle Sort
static void cycleSort(int[] arr) {
int n = arr.length;
int i = 0;
// Traverse array
while (i < n) {
// Correct index of current element
int correct = arr[i] - 1;
// If element is not at correct position, swap
if (arr[i] != arr[correct]) {
int temp = arr[i];
arr[i] = arr[correct];
arr[correct] = temp;
}
// Else move to next index
else {
i++;
}
}
}
public static void main(String[] args) {
int[] arr = {3, 2, 4, 5, 1};
int n = arr.length;
cycleSort(arr);
for (int i = 0; i < n; i++)
System.out.print(arr[i] + " ");
}
}
# Function to perform Cycle Sort
def cycleSort(arr):
n = len(arr)
i = 0
# Traverse array
while i < n:
# Correct index of current element
correct = arr[i] - 1
# If element is not at correct position, swap
if arr[i] != arr[correct]:
arr[i], arr[correct] = arr[correct], arr[i]
else:
# Move to next index
i += 1
if __name__ == "__main__":
arr = [3, 2, 4, 5, 1]
n = len(arr)
cycleSort(arr)
for i in range(n):
print(arr[i], end=" ")
using System;
class GFG {
// Function to perform Cycle Sort
static void cycleSort(int[] arr) {
int n = arr.Length;
int i = 0;
// Traverse array
while (i < n) {
// Correct index
int correct = arr[i] - 1;
// Swap if needed
if (arr[i] != arr[correct]) {
int temp = arr[i];
arr[i] = arr[correct];
arr[correct] = temp;
}
else {
// Move to next index
i++;
}
}
}
static void Main() {
int[] arr = {3, 2, 4, 5, 1};
int n = arr.Length;
cycleSort(arr);
foreach (int x in arr)
Console.Write(x + " ");
}
}
// Function to perform Cycle Sort
function cycleSort(arr) {
let i = 0;
let n = arr.length;
// Traverse array
while (i < n) {
// Correct index of current element
let correct = arr[i] - 1;
// Swap if not in correct position
if (arr[i] !== arr[correct]) {
[arr[i], arr[correct]] = [arr[correct], arr[i]];
} else {
// Move to next index
i++;
}
}
}
// Driver code
let arr = [3, 2, 4, 5, 1];
cycleSort(arr);
console.log(arr.join(" "));
Output
1 2 3 4 5
Advantage of Cycle Sort
- Auxiliary Space is O(1)
- in-place sorting algorithm.
- A minimum number of writes to the memory
- Cycle sort is useful when the array is stored in EEPROM or FLASH.
- The idea of Cycle Sort is used in problems like Minimum Missing Positive and Min Swaps to Sort
Disadvantage of Cycle Sort
- Time complexity is O(n²) for general case
- Not stable
- Not suitable for large datasets