Cycle Sort

Cycle Sort is a sort designed to make the fewest data moves possible. Cycle Sort's complexity differs depending on the variant, but in general, the complexity comes from the time it takes to find an element's final position in the sorted list. Cycle Sort is also not stable, but there are variants such as Stable Cycle that are.

Algorithm
Cycle Sort starts at the first position $$i=0$$ and finds the final destination of the item at $$i$$. It then swaps $$i$$ with the item's destination then finds the destination of the new item at $$i$$ and repeats. If at any point the destination is $$=i$$, Cycle Sort increments $$i$$ instead of swapping. It repeats these processes until it reaches the end of the list.

Since each element is swapped to its final destination, they are swapped at most once and never moved again therefore Cycle Sort makes $$O(n)$$ moves. The simplest version Cycle Sort is generally implemented in $$O(n^2)$$ comparisons and $$O(1)$$ space. To find an item's destination, Cycle Sort iterates through the list counting the amount of elements less that the item. This requires $$O(n)$$ comparisons for $$O(n)$$ items therefore Cycle Sort is $$O(n^2)$$.

Handling equal items
The method given above, however, only works with distinct elements. In the case of equal elements, this method fails by putting Cycle Sort in a perpetual loop. A simple example of this happening is $$arr = [1, 1, 0]$$. Cycle Sort swaps the first $$1$$ in $$arr[0]$$ with $$arr[1]$$ since that is $$1$$'s final destination. However, the item we swapped with is another $$1$$ which swaps to the same position, so the algorithm gets stuck swapping $$arr[0]$$ with $$arr[1]$$ forever.

The solution is to add a check for items equal to the item being swapped away. If Cycle Sort finds that the item in the final destination is equal, it skips that position by incrementing to the right. This ensures that Cycle Sort always swaps distinct items and therefore never gets stuck in an infinite loop. This step also adds an extra worst case of $$O(n)$$ comparisons per element.

Another solution is to allocate $$O(n)$$ extra space and assign a key to each element making them all distinct which avoids this problem entirely.

Writes optimization
Cycle Sort using swaps does not achieve optimal writes as 2 writes are made per item therefore yielding $$2n$$ writes. One can make the observation that Cycle Sort swaps the items to the same location $$i$$ in the main array while chasing the cycle. Therefore, Cycle Sort can swap to an external location instead which removes the need for writing to $$i$$ in the main array. temp  = arr[i] #          | 1 data move arr[i] = arr[j] # 1 write | 2 data moves arr[j] = temp  # 2 writes | 3 data moves temp1 = arr[i] # temp1 represents arr[i] throughout the cycle temp2 = temp1  #          | 1 data move temp1 = arr[j] #          | 2 data moves arr[j] = temp2 # 1 write  | 3 data moves With this optimization, Cycle sort makes 1 write per item reducing the overall writes from $$2n$$ to $$n$$ which is optimal. However, the amount of data moves remains unchanged: 3 per element and $$3n$$ in total which is suboptimal. The variant Backwards Cycle Sort makes optimal writes and data moves but require $$O(n^3)$$ comparisons for a simple in-place implementation.
 * 1) unoptimized
 * 1) optimized

Pseudocode
procedure cycle_sort(array arr) do for i from 0 to length(arr)-1 do dest = destination of arr[i] # depending on the type of cycle sort this can be O(1), O(n), etc.      while dest != i do swap i and dest in arr dest = destination of arr[i] end while end for end

Implementation
Implementation of in-place $$O(n^2)$$ Cycle Sort using optimal writes to array in Java:

Backwards Cycle
While Cycle Sort swaps $$i$$ and $$dest(arr[i])$$ and repeats, Backwards Cycle sort searches the list for an item at $$j$$ such that $$dest(array[j])=i$$. It then repeats on $$j$$ until the algorithm ends up on the original starting point ($$j=i$$). Backwards Cycle therefore chases the cycle backwards hence the name.

Pseudocode
procedure backwards_cycle_sort(array arr) do for i from 0 to length(arr)-1 do if destination of arr[i] != i do temp = arr[i] j   = i          next = destination of arr[i] while next != i do arr[j] = arr[next] j = next next = position of item such that destination of arr[next] == j         end while arr[j] = temp end if end for end

Bingo Cycle
A cross between Cycle Sort and Bingo Sort which is a Selection Sort variant that swaps equal elements into their correct place. Instead of swapping the minimum or maximum values each time, Bingo Cycle finds the destination of a single element then swaps all equal elements start from the destination. Like Bingo Sort, this makes Bingo Cycle adaptive on distributions with few unique keys. However, Bingo Sort is no longer write optimal and requires at most $$n$$ swaps or $$2n$$ writes which is no better than Bingo Sort. It is also more complicated to implement a swap optimal Bingo Cycle than a Bingo Sort in which the latter is already swap optimal.

Stable Cycle
Stable Cycle is Cycle sort but maintains the order of the elements using $$O(n^2)$$ comparisons and $$O(n)$$ extra bits instead of indices. While there are not many practical applications for this algorithm, Stable Cycle is of great theoretical interest as it is a main component of a bufferless in-place $$O(n)$$ time stable partition. Stable Cycle also lends itself to In-Place Stable Cycle Sort which is also stable and $$O(n^2)$$ time but without the extra $$O(n)$$ space therefore contributing to one of the first examples of an in-place stable $$O(n)$$ moves algorithm.