mirror of
https://hub.njuu.cf/TheAlgorithms/Python.git
synced 2023-10-11 13:06:12 +08:00
20b21e5ec9
* Refactor cycle_sort * Undo changes to keep only doctests
64 lines
1.6 KiB
Python
64 lines
1.6 KiB
Python
"""
|
|
Code contributed by Honey Sharma
|
|
Source: https://en.wikipedia.org/wiki/Cycle_sort
|
|
"""
|
|
|
|
|
|
def cycle_sort(array: list) -> list:
|
|
"""
|
|
>>> cycle_sort([4, 3, 2, 1])
|
|
[1, 2, 3, 4]
|
|
|
|
>>> cycle_sort([-4, 20, 0, -50, 100, -1])
|
|
[-50, -4, -1, 0, 20, 100]
|
|
|
|
>>> cycle_sort([-.1, -.2, 1.3, -.8])
|
|
[-0.8, -0.2, -0.1, 1.3]
|
|
|
|
>>> cycle_sort([])
|
|
[]
|
|
"""
|
|
ans = 0
|
|
|
|
# Pass through the array to find cycles to rotate.
|
|
for cycleStart in range(0, len(array) - 1):
|
|
item = array[cycleStart]
|
|
|
|
# finding the position for putting the item.
|
|
pos = cycleStart
|
|
for i in range(cycleStart + 1, len(array)):
|
|
if array[i] < item:
|
|
pos += 1
|
|
|
|
# If the item is already present-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]
|
|
ans += 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]
|
|
ans += 1
|
|
|
|
return array
|
|
|
|
|
|
if __name__ == "__main__":
|
|
assert cycle_sort([4, 5, 3, 2, 1]) == [1, 2, 3, 4, 5]
|
|
assert cycle_sort([0, 1, -10, 15, 2, -2]) == [-10, -2, 0, 1, 2, 15]
|