这真的可能吗?我在维基百科上发现了它,但我还不能完全可视化这个过程,所以我不知道我需要做些什么才能使它稳定下来。

最佳答案

首先,注意只有一个步骤可以改变元素的顺序:第一个步骤。剩下的步骤都是递归步骤。改变任何递归步骤都会改变算法的基本特性,这样如果我们不这样递归,它就不再是stooge排序了(这三个递归调用看起来是典型的“stoogey”)
第一步也很简单,改变它似乎也会改变算法的特性。但我们可以对其进行调整:如果初始元素大于最终元素,则将等于最终元素的第一个元素a与等于初始元素之前的最后一个元素交换,我们可以通过一次传递找到该元素。令人惊讶的是,即使内环现在是O(n)而不是O(1),但Stooge Sort表明O(n ^ 2.71)的复杂度保持不变。同样,如果所有元素都是唯一的,则会出现与原始Stooge排序中相同的交换序列,这使得此版本成为近亲。
为了快速描述为什么这个版本是稳定的,可以考虑将两个相等元素的重新排序作为“坏交换”。我们声称,使用上述方法没有不良掉期。原因是,对于任何交换,我们知道在两个元素之间没有元素等于任何一个元素由于等元保持相同的顺序,算法是稳定的。
算法正确性的证明类似于原stooge排序正确性的证明。这是一个常见的家庭作业问题,所以我不想泄露,但它遵循归纳假设。
如果tweak的描述有点简洁,那么下面是一个java实现。

import java.util.Arrays;
import java.util.Random;

public class StableStooge {
    public static class FooBar implements Comparable<FooBar> {
        public final int foo;
        public final int bar;

        public FooBar(int foo, int bar) {
            this.foo = foo;
            this.bar = bar;
        }

        @Override
        public int compareTo(FooBar arg0) {
            return foo - arg0.foo;
        }

        public String toString() {
            return foo +":"+bar;
        }
    }

    private static void sort(Comparable[] c, int start, int end) {
        if (start >= end) return;
        if (c[start].compareTo(c[end]) > 0) {
            // Find the first thing X equal to end and the last thing Y which is before X and equal to start
            int lastindex = end;
            int firstindex = start;
            for (int i = start + 1; i < end; i++) {
                if (c[end].compareTo(c[i]) == 0) {
                    lastindex = i;
                    break;
                } else if (c[start].compareTo(c[i]) == 0) {
                    firstindex = i;
                }
            }
            Comparable tmp = c[firstindex];
            c[firstindex] = c[lastindex];
            c[lastindex] = tmp;
        }
        // Recurse
        if (end - start + 1 >= 3) {
            int third = (end - start + 1) / 3;
            sort(c, start, end-third);
            sort(c, start+third, end);
            sort(c, start, end-third);
        }
    }

    public static void sort(Comparable[] c) {
        sort(c, 0, c.length-1);
    }

    public static void main(String[] args) {
        FooBar[] test = new FooBar[100];
        FooBar[] testsav = new FooBar[100];
        Random r = new Random();
        for (int i = 0; i < 1000; i++) {
            for (int j = 0; j < test.length; j++) {
                test[j] = new FooBar(r.nextInt(10), j);
                testsav[j] = test[j];
            }
            sort(test);
            // verify
            for (int j = 1; j < test.length; j++) {
                if (test[j].foo < test[j-1].foo) {
                    throw new RuntimeException("Bad sort");
                }
                if (test[j].foo == test[j-1].foo && test[j].bar <= test[j-1].bar) {
                    throw new RuntimeException("Unstable sort: "+Arrays.toString(testsav)+" sorted improperly to "+Arrays.toString(test));
                }
            }
        }
    }
}

关于algorithm - Stooge Sort的稳定执行?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10574985/

10-12 22:27