サイクルソートは、ソートしている順列をサイクルに因数分解できるという考えに基づいたインプレースソートです。各サイクルを1位置回転すると、配列が並べ替えられます。これは簡単にコーディングできるため、配列への書き込み数は、インプレースソートに必要な理論上の最小値になります(これは、書き込み数を最小限に抑えたいフラッシュドライブなどの巨大なデータセットに適しています。デバイス)。
ウィキペディアのコードをインプレースソートに保ち、最適な書き込み数を維持しながら、コードの実行時間を改善する方法はありますか、それとも最高の方法ですか?
これが実装です(からにrange(a, b)
行くことに注意してください):a
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