循环排序算法

发布于 2024-12-11 11:05:19 字数 91 浏览 1 评论 0原文

我在浏览互联网时发现有一种称为循环排序的算法,它可以使内存写入次数最少。但是我无法在任何地方找到该算法。如何检测一个循环中是否存在循环大批? 谁能给这个算法完整的解释?

I was browsing through the internet when i found out that there is an algorithm called cycle sort which makes the least number of memory writes.But i am not able to find the algorithm anywhere.How to detect whether a cycle is there or not in an array?
Can anybody give a complete explanation for this algorithm?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

任性一次 2024-12-18 11:05:20

循环排序算法的动机是循环分解 。循环分解最好通过示例来解释。假设您有这个数组:

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 交换到 1 所在的位置。换句话说,元素 1 和 3 向前循环一个位置。

根据上述观察,我们可以说序列 4 3 0 1 2 具有循环分解 (0 2 4)(1 3)。这里,括号中的每组术语的意思是“向前循环这些元素”。这意味着将 0 循环到 2 所在的位置,将 2 循环到 4 所在的位置,将 4 循环到 0 所在的位置,然后将 1 循环到 3 所在的位置,将 3 循环到 1 所在的位置。

如果您对特定数组进行循环分解,则可以按排序顺序将其返回,只需将所有内容向后循环一个位置即可实现最少的写入次数。 循环排序背后的想法是尝试确定输入数组的循环分解是什么,然后反转它,将所有东西放回原位。

这样做的部分挑战是弄清楚所有东西最初所属的位置,因为循环分解假设您知道这一点。通常,循环排序的工作原理是查找每个元素并计算有多少个元素小于该元素。这是昂贵的 - 它会影响排序算法的 Θ(n2) 运行时间 - 但不需要任何写入。

The cycle sort algorithm is motivated by something called a cycle decomposition. Cycle decompositions are best explained by example. Let's suppose that you have this array:

4 3 0 1 2

Let's imagine that we have this sequence in sorted order, as shown here:

0 1 2 3 4

How would we have to shuffle this sorted array to get to the shuffled version? Well, let's place them side-by-side:

0 1 2 3 4
4 3 0 1 2

Let's start from the beginning. Notice that the number 0 got swapped to the position initially held by 2. The number 2, in turn, got swapped to the position initially held by 4. Finally, 4 got swapped to the position initially held by 0. In other words, the elements 0, 2, and 4 all were cycled forward one position. That leaves behind the numbers 1 and 3. Notice that 1 swaps to where 3 is and 3 swaps to where 1 is. In other words, the elements 1 and 3 were cycled forward one position.

As a result of the above observations, we'd say that the sequence 4 3 0 1 2 has cycle decomposition (0 2 4)(1 3). Here, each group of terms in parentheses means "circularly cycle these elements forward." This means to cycle 0 to the spot where 2 is, 2 to the spot where 4 is, and 4 to the spot where 0 was, then to cycle 1 to the spot where 3 was and 3 to the spot where 1 is.

If you have the cycle decomposition for a particular array, you can get it back in sorted order making the fewest number of writes by just cycling everything backward one spot. The idea behind cycle sort is to try to determine what the cycle decomposition of the input array is, then to reverse it to put everything back in its place.

Part of the challenge of this is figuring out where everything initially belongs since a cycle decomposition assumes you know this. Typically, cycle sort works by going to each element and counting up how many elements are smaller than it. This is expensive - it contributes to the Θ(n2) runtime of the sorting algorithm - but doesn't require any writes.

兮颜 2024-12-18 11:05:20

如果有人需要的话,这里有一个 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

here's a python implementation if anyone needs

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文