循环排序算法

时间:2011-10-22 08:52:32

标签: algorithm sorting cycle-sort

当我发现有一种称为循环排序的算法时,我正在浏览互联网,这使得内存写入次数最少。但是我无法在任何地方找到算法。如何检测循环是否存在或者不在阵列? 任何人都能对这个算法做出完整的解释吗?

2 个答案:

答案 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