当我发现有一种称为循环排序的算法时,我正在浏览互联网,这使得内存写入次数最少。但是我无法在任何地方找到算法。如何检测循环是否存在或者不在阵列? 任何人都能对这个算法做出完整的解释吗?
答案 0 :(得分:14)
循环排序算法的动机是 cycle decomposition 。循环分解最好用例子来解释。我们假设你有这个数组:
4 3 0 1 2
让我们假设我们按排序顺序排列这个序列,如下所示:
0 1 2 3 4
我们如何将这个排序的数组混乱以获得洗牌版本?好吧,让我们把它们放在一起:
0 1 2 3 4
4 3 0 1 2
让我们从头开始。注意,数字0被交换到最初由2持有的位置。反过来,数字2被交换到最初由4保持的位置。最后,4被交换到最初由0保持的位置。换句话说,元素0,2和4都向前循环一个位置。这留下了数字1和3.注意1交换到3是3和3交换到1是。换句话说,元素1和3在一个位置向前循环。
作为上述观察的结果,我们说序列4 3 0 1 2具有循环分解(0 2 4)(1 3)。这里,括号中的每组术语意味着“循环循环这些元素”。这意味着循环0到2的位置,2到4的位置,4到0的位置,然后循环1到3的位置,3到1的位置。
如果您对特定数组进行循环分解,则可以按排序顺序将其取回,通过将所有内容向后循环一个点来创建最少的写入次数。 cycle sort背后的想法是尝试确定输入数组的循环分解是什么,然后反转它以将所有内容放回原位。
这样做的部分挑战是弄清楚最初所有的东西,因为循环分解假定你知道这一点。通常,循环排序通过转到每个元素并计算有多少元素小于它来工作。这很昂贵 - 它有助于排序算法的Θ(n 2 )运行时 - 但不需要任何写入。
答案 1 :(得分:0)
这是一个python实现,如果有人需要
def cycleSort(vector):
writes = 0
# Loop through the vector to find cycles to rotate.
for cycleStart, item in enumerate(vector):
# Find where to put the item.
pos = cycleStart
for item2 in vector[cycleStart + 1:]:
if item2 < 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 == vector[pos]:
pos += 1
vector[pos], item = item, vector[pos]
writes += 1
# Rotate the rest of the cycle.
while pos != cycleStart:
# Find where to put the item.
pos = cycleStart
for item2 in vector[cycleStart + 1:]:
if item2 < item:
pos += 1
# Put the item there or right after any duplicates.
while item == vector[pos]:
pos += 1
vector[pos], item = item, vector[pos]
writes += 1
return writes
x = [0, 1, 2, 2, 2, 2, 1, 9, 3.5, 5, 8, 4, 7, 0, 6]
w = cycleSort(x)
print w, x