Cycle sort is an in-place sort based on the idea that the permutation you're sorting can be factored into cycles. If you rotate each cycle one position, the array will be sorted. This can easily be coded so that the number of writes to the array is the theoretical minimum needed for any in-place sort (which is nice for huge data sets on, say, Flash drives, where you want to minimize the number of writes to the device).
Are there any ways to improve the run time of the code on Wikipedia while keeping it an in-place sort and maintaining the optimal number of writes or is it the best it can be?
Here is the implementation (note that range(a, b)
goes from a
to b - 1
) :
# Sort an array in place and return the number of writes.
def cycleSort(array):
writes = 0
# Loop through the array to find cycles to rotate.
for cycleStart in range(0, len(array) - 1):
item = array[cycleStart]
# Find where to put the item.
pos = cycleStart
for i in range(cycleStart + 1, len(array)):
if array[i] < item:
pos += 1
# If the item is already there, this is not a cycle.
if pos == cycleStart:
continue
# Otherwise, put the item there or right after any duplicates.
while item == array[pos]:
pos += 1
array[pos], item = item, array[pos]
writes += 1
# Rotate the rest of the cycle.
while pos != cycleStart:
# Find where to put the item.
pos = cycleStart
for i in range(cycleStart + 1, len(array)):
if array[i] < item:
pos += 1
# Put the item there or right after any duplicates.
while item == array[pos]:
pos += 1
array[pos], item = item, array[pos]
writes += 1
return writes